Browse Source

Enhance IM functionality

pull/116/head
cKey 5 years ago
parent
commit
fce050f1ea
  1. 23
      aspnet-core/LINGYUN.MicroService.sln
  2. 20
      aspnet-core/database/ApiGateway-Init-SqlServer.sql
  3. 98
      aspnet-core/database/ApiGateway-Init.sql
  4. 15
      aspnet-core/modules/common/LINGYUN.Abp.AspNetCore.SignalR.Protocol.Json/LINGYUN.Abp.AspNetCore.SignalR.Protocol.Json.csproj
  5. 22
      aspnet-core/modules/common/LINGYUN.Abp.AspNetCore.SignalR.Protocol.Json/LINGYUN/Abp/AspNetCore/SignalR/Protocol/Json/AbpAspNetCoreSignalRProtocolJsonModule.cs
  6. 15
      aspnet-core/modules/common/LINGYUN.Abp.ExceptionHandling.Notifications/LINGYUN.Abp.ExceptionHandling.Notifications.csproj
  7. 22
      aspnet-core/modules/common/LINGYUN.Abp.ExceptionHandling.Notifications/LINGYUN/Abp/ExceptionHandling/Notifications/AbpExceptionHandlingNotificationDefinitionProvider.cs
  8. 3
      aspnet-core/modules/common/LINGYUN.Abp.ExceptionHandling.Notifications/LINGYUN/Abp/ExceptionHandling/Notifications/AbpExceptionHandlingNotificationNames.cs
  9. 19
      aspnet-core/modules/common/LINGYUN.Abp.ExceptionHandling.Notifications/LINGYUN/Abp/ExceptionHandling/Notifications/AbpNotificationsExceptionHandlingModule.cs
  10. 29
      aspnet-core/modules/common/LINGYUN.Abp.ExceptionHandling.Notifications/LINGYUN/Abp/ExceptionHandling/Notifications/AbpNotificationsExceptionSubscriber.cs
  11. 7
      aspnet-core/modules/common/LINGYUN.Abp.ExceptionHandling.Notifications/LINGYUN/Abp/ExceptionHandling/Notifications/Localization/Resources/en.json
  12. 7
      aspnet-core/modules/common/LINGYUN.Abp.ExceptionHandling.Notifications/LINGYUN/Abp/ExceptionHandling/Notifications/Localization/Resources/zh-Hans.json
  13. 2
      aspnet-core/modules/common/LINGYUN.Abp.ExceptionHandling/LINGYUN.Abp.ExceptionHandling.csproj
  14. 12
      aspnet-core/modules/common/LINGYUN.Abp.ExceptionHandling/LINGYUN/Abp/ExceptionHandling/AbpExceptionHandlingModule.cs
  15. 9
      aspnet-core/modules/common/LINGYUN.Abp.ExceptionHandling/LINGYUN/Abp/ExceptionHandling/Localization/ExceptionHandlingResource.cs
  16. 9
      aspnet-core/modules/common/LINGYUN.Abp.IM.SignalR/LINGYUN/Abp/IM/SignalR/AbpIMSignalRModule.cs
  17. 74
      aspnet-core/modules/common/LINGYUN.Abp.IM.SignalR/LINGYUN/Abp/IM/SignalR/Hubs/MessagesHub.cs
  18. 15
      aspnet-core/modules/common/LINGYUN.Abp.IM.SignalR/LINGYUN/Abp/IM/SignalR/Messages/SignalRMessageSenderProvider.cs
  19. 1
      aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN.Abp.IM.csproj
  20. 10
      aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/AbpIMModule.cs
  21. 15
      aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/AbpIMOptions.cs
  22. 47
      aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/Contract/IFriendStore.cs
  23. 44
      aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/Group/IUserGroupStore.cs
  24. 2
      aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/Messages/ChatMessage.cs
  25. 10
      aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/Messages/IMessageSenderProvider.cs
  26. 9
      aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/Messages/IMessageSenderProviderManager.cs
  27. 20
      aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/Messages/IMessageStore.cs
  28. 26
      aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/Messages/MessageSender.cs
  29. 47
      aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/Messages/MessageSenderBase.cs
  30. 70
      aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/Messages/MessageSenderProviderBase.cs
  31. 33
      aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/Messages/MessageSenderProviderManager.cs
  32. 26
      aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/Messages/NullMessageSender.cs
  33. 41
      aspnet-core/modules/common/LINGYUN.Abp.Notifications.SignalR/LINGYUN/Abp/Notifications/SignalR/Hubs/NotificationsHub.cs
  34. 71
      aspnet-core/modules/common/LINGYUN.Abp.Notifications.SignalR/LINGYUN/Abp/Notifications/SignalR/SignalRNotificationPublishProvider.cs
  35. 1
      aspnet-core/modules/common/LINGYUN.Abp.Notifications.WeChat/LINGYUN.Abp.Notifications.WeChat.WeApp.csproj
  36. 54
      aspnet-core/modules/common/LINGYUN.Abp.Notifications.WeChat/LINGYUN/Abp/Notifications/WeChat/WeApp/Features/WeChatWeAppFeatureDefinitionProvider.cs
  37. 30
      aspnet-core/modules/common/LINGYUN.Abp.Notifications.WeChat/LINGYUN/Abp/Notifications/WeChat/WeApp/Features/WeChatWeAppFeatures.cs
  38. 5
      aspnet-core/modules/common/LINGYUN.Abp.Notifications.WeChat/LINGYUN/Abp/Notifications/WeChat/WeApp/IWeChatWeAppNotificationSender.cs
  39. 58
      aspnet-core/modules/common/LINGYUN.Abp.Notifications.WeChat/LINGYUN/Abp/Notifications/WeChat/WeApp/WeChatWeAppNotificationPublishProvider.cs
  40. 21
      aspnet-core/modules/common/LINGYUN.Abp.Notifications.WeChat/LINGYUN/Abp/Notifications/WeChat/WeApp/WeChatWeAppNotificationSender.cs
  41. 5
      aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/AbpNotificationModule.cs
  42. 15
      aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/INotificationDefinitionContext.cs
  43. 6
      aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/INotificationDefinitionManager.cs
  44. 41
      aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/INotificationDispatcher.cs
  45. 41
      aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/INotificationSender.cs
  46. 151
      aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/INotificationStore.cs
  47. 53
      aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/INotificationSubscriptionManager.cs
  48. 220
      aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/Internal/DefaultNotificationDispatcher.cs
  49. 78
      aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/Internal/NotificationSender.cs
  50. 72
      aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/Internal/NotificationSubscriptionManager.cs
  51. 23
      aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/LocalizableStringInfo.cs
  52. 91
      aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationData.cs
  53. 31
      aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationDataConverter.cs
  54. 14
      aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationDataMappingDictionary.cs
  55. 27
      aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationDefinition.cs
  56. 46
      aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationDefinitionContext.cs
  57. 78
      aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationDefinitionManager.cs
  58. 30
      aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationEventData.cs
  59. 70
      aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationGroupDefinition.cs
  60. 30
      aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationInfo.cs
  61. 14
      aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationName.cs
  62. 15
      aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationNameNormalizer.cs
  63. 4
      aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationPublishJob.cs
  64. 12
      aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationPublishProvider.cs
  65. 123
      aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NullNotificationStore.cs
  66. 8
      aspnet-core/modules/common/LINGYUN.Abp.RealTime.SignalR/Class1.cs
  67. 1
      aspnet-core/modules/common/LINGYUN.Abp.RealTime.SignalR/LINGYUN/Abp/RealTime/SignalR/AbpRealTimeSignalRModule.cs
  68. 86
      aspnet-core/modules/common/LINGYUN.Abp.RealTime.SignalR/LINGYUN/Abp/RealTime/SignalR/Hubs/OnlineClientHubBase.cs
  69. 10
      aspnet-core/modules/common/LINGYUN.Abp.RealTime/LINGYUN/Abp/RealTime/Client/IClient.cs
  70. 6
      aspnet-core/modules/common/LINGYUN.Abp.RealTime/LINGYUN/Abp/RealTime/Client/IOnlineClient.cs
  71. 3
      aspnet-core/modules/common/LINGYUN.Abp.RealTime/LINGYUN/Abp/RealTime/Client/IOnlineClientManager.cs
  72. 6
      aspnet-core/modules/common/LINGYUN.Abp.RealTime/LINGYUN/Abp/RealTime/Client/IOnlineClientStore.cs
  73. 12
      aspnet-core/modules/common/LINGYUN.Abp.RealTime/LINGYUN/Abp/RealTime/Client/InMemoryOnlineClientStore.cs
  74. 11
      aspnet-core/modules/common/LINGYUN.Abp.RealTime/LINGYUN/Abp/RealTime/Client/OnlineClient.cs
  75. 11
      aspnet-core/modules/common/LINGYUN.Abp.RealTime/LINGYUN/Abp/RealTime/Client/OnlineClientManager.cs
  76. 4
      aspnet-core/modules/common/LINGYUN.Abp.WeChat.Authorization/LINGYUN.Abp.WeChat.Authorization.csproj
  77. 5
      aspnet-core/modules/common/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/AbpWeChatAuthorizationModule.cs
  78. 12
      aspnet-core/modules/common/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/OpenId/IUserWeChatCodeFinder.cs
  79. 7
      aspnet-core/modules/common/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/OpenId/IWeChatOpenIdFinder.cs
  80. 19
      aspnet-core/modules/common/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/OpenId/NullUserWeChatCodeFinder.cs
  81. 6
      aspnet-core/modules/common/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/OpenId/WeChatOpenIdCacheItem.cs
  82. 27
      aspnet-core/modules/common/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/OpenId/WeChatOpenIdFinder.cs
  83. 5
      aspnet-core/modules/common/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/Token/IWeChatTokenProvider.cs
  84. 13
      aspnet-core/modules/common/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/Token/WeChatTokenProvider.cs
  85. 22
      aspnet-core/modules/common/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/WeChatAuthorizationConsts.cs
  86. 1
      aspnet-core/modules/identity/LINGYUN.Abp.Identity.Application.Contracts/LINGYUN/Abp/Identity/IIdentityUserAppService.cs
  87. 8
      aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN/Abp/IdentityServer/WeChatValidator/WeChatTokenGrantValidator.cs
  88. 40
      aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN/Abp/WeChat/Authorization/UserWeChatCodeFinder.cs
  89. 7
      aspnet-core/modules/message/LINGYUN.Abp.MessageService.Application.Contracts/LINGYUN/Abp/MessageService/Chat/Dto/MyFriendAddRequestDto.cs
  90. 1
      aspnet-core/modules/message/LINGYUN.Abp.MessageService.Application.Contracts/LINGYUN/Abp/MessageService/Chat/Dto/MyFriendCreateDto.cs
  91. 2
      aspnet-core/modules/message/LINGYUN.Abp.MessageService.Application.Contracts/LINGYUN/Abp/MessageService/Chat/IMyFriendAppService.cs
  92. 4
      aspnet-core/modules/message/LINGYUN.Abp.MessageService.Application.Contracts/LINGYUN/Abp/MessageService/Localization/ApplicationContracts/en.json
  93. 4
      aspnet-core/modules/message/LINGYUN.Abp.MessageService.Application.Contracts/LINGYUN/Abp/MessageService/Localization/ApplicationContracts/zh-Hans.json
  94. 28
      aspnet-core/modules/message/LINGYUN.Abp.MessageService.Application.Contracts/LINGYUN/Abp/MessageService/Notifications/Dto/NotificationDto.cs
  95. 11
      aspnet-core/modules/message/LINGYUN.Abp.MessageService.Application.Contracts/LINGYUN/Abp/MessageService/Notifications/Dto/NotificationGroupDto.cs
  96. 22
      aspnet-core/modules/message/LINGYUN.Abp.MessageService.Application.Contracts/LINGYUN/Abp/MessageService/Notifications/Dto/NotificationSendDto.cs
  97. 2
      aspnet-core/modules/message/LINGYUN.Abp.MessageService.Application.Contracts/LINGYUN/Abp/MessageService/Notifications/Dto/UserNotificationGetByPagedDto.cs
  98. 21
      aspnet-core/modules/message/LINGYUN.Abp.MessageService.Application.Contracts/LINGYUN/Abp/MessageService/Notifications/IMyNotificationAppService.cs
  99. 41
      aspnet-core/modules/message/LINGYUN.Abp.MessageService.Application.Contracts/LINGYUN/Abp/MessageService/Notifications/INotificationAppService.cs
  100. 7
      aspnet-core/modules/message/LINGYUN.Abp.MessageService.Application.Contracts/LINGYUN/Abp/MessageService/Permissions/MessageServicePermissions.cs

23
aspnet-core/LINGYUN.MicroService.sln

@ -253,7 +253,13 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Account.Web", "
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.AspNetCore.SignalR.JwtToken", "modules\common\LINGYUN.Abp.AspNetCore.SignalR\LINGYUN.Abp.AspNetCore.SignalR.JwtToken.csproj", "{A66D48C9-F141-4111-9169-CEB64AFFF61D}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.AspNetCore.SignalR.JwtToken", "modules\common\LINGYUN.Abp.AspNetCore.SignalR\LINGYUN.Abp.AspNetCore.SignalR.JwtToken.csproj", "{A66D48C9-F141-4111-9169-CEB64AFFF61D}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.RealTime.SignalR", "modules\common\LINGYUN.Abp.RealTime.SignalR\LINGYUN.Abp.RealTime.SignalR.csproj", "{524276E1-053D-4191-ABF7-4CDA01BFFBC3}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.RealTime.SignalR", "modules\common\LINGYUN.Abp.RealTime.SignalR\LINGYUN.Abp.RealTime.SignalR.csproj", "{524276E1-053D-4191-ABF7-4CDA01BFFBC3}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.AspNetCore.SignalR.Protocol.Json", "modules\common\LINGYUN.Abp.AspNetCore.SignalR.Protocol.Json\LINGYUN.Abp.AspNetCore.SignalR.Protocol.Json.csproj", "{43083268-74DE-4C68-824A-FB0CEC77358D}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "wechat", "wechat", "{DD9BE9E7-F6BF-4869-BCD2-82F5072BDA21}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.WeChat", "modules\wechat\LINGYUN.Abp.WeChat\LINGYUN.Abp.WeChat.csproj", "{BAE74ABC-1096-495F-A624-BEBFBC1896F2}"
EndProject EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -677,6 +683,14 @@ Global
{524276E1-053D-4191-ABF7-4CDA01BFFBC3}.Debug|Any CPU.Build.0 = Debug|Any CPU {524276E1-053D-4191-ABF7-4CDA01BFFBC3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{524276E1-053D-4191-ABF7-4CDA01BFFBC3}.Release|Any CPU.ActiveCfg = Release|Any CPU {524276E1-053D-4191-ABF7-4CDA01BFFBC3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{524276E1-053D-4191-ABF7-4CDA01BFFBC3}.Release|Any CPU.Build.0 = Release|Any CPU {524276E1-053D-4191-ABF7-4CDA01BFFBC3}.Release|Any CPU.Build.0 = Release|Any CPU
{43083268-74DE-4C68-824A-FB0CEC77358D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{43083268-74DE-4C68-824A-FB0CEC77358D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{43083268-74DE-4C68-824A-FB0CEC77358D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{43083268-74DE-4C68-824A-FB0CEC77358D}.Release|Any CPU.Build.0 = Release|Any CPU
{BAE74ABC-1096-495F-A624-BEBFBC1896F2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BAE74ABC-1096-495F-A624-BEBFBC1896F2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BAE74ABC-1096-495F-A624-BEBFBC1896F2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BAE74ABC-1096-495F-A624-BEBFBC1896F2}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
@ -736,8 +750,8 @@ Global
{0D1DB712-B48D-4FB7-9A47-694C668A62E3} = {608A3BD0-FC8D-48B0-B1C5-F3203A3BE99F} {0D1DB712-B48D-4FB7-9A47-694C668A62E3} = {608A3BD0-FC8D-48B0-B1C5-F3203A3BE99F}
{9E12ADBF-713B-4FE7-B71F-52B5078A57CE} = {3CDBA2A6-DC8A-48C5-8A6C-AF207394B43D} {9E12ADBF-713B-4FE7-B71F-52B5078A57CE} = {3CDBA2A6-DC8A-48C5-8A6C-AF207394B43D}
{02043AD5-5E06-4EDD-8162-983E766C38EC} = {0439B173-F41E-4CE0-A44A-CCB70328F272} {02043AD5-5E06-4EDD-8162-983E766C38EC} = {0439B173-F41E-4CE0-A44A-CCB70328F272}
{85EF4251-EFC4-4CC9-912B-EA5DB1E2E359} = {8AC72641-30D3-4ACF-89FA-808FADC55C2E} {85EF4251-EFC4-4CC9-912B-EA5DB1E2E359} = {DD9BE9E7-F6BF-4869-BCD2-82F5072BDA21}
{263A8A1C-69D0-4C3F-B33E-8F0831C146EB} = {8AC72641-30D3-4ACF-89FA-808FADC55C2E} {263A8A1C-69D0-4C3F-B33E-8F0831C146EB} = {DD9BE9E7-F6BF-4869-BCD2-82F5072BDA21}
{47CC8F7A-681D-42B9-AE04-78453782C1B6} = {8AC72641-30D3-4ACF-89FA-808FADC55C2E} {47CC8F7A-681D-42B9-AE04-78453782C1B6} = {8AC72641-30D3-4ACF-89FA-808FADC55C2E}
{F595CB9F-B117-4D62-A1AE-48599927DB36} = {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} {5CF403B2-47C9-4E4E-8856-0294BDD64884} = {8AC72641-30D3-4ACF-89FA-808FADC55C2E}
@ -805,6 +819,9 @@ Global
{5F43141B-6C63-4547-B9D6-D69EC3D7CA7E} = {9E72FEB9-A626-4312-892B-CDD043879758} {5F43141B-6C63-4547-B9D6-D69EC3D7CA7E} = {9E72FEB9-A626-4312-892B-CDD043879758}
{A66D48C9-F141-4111-9169-CEB64AFFF61D} = {8AC72641-30D3-4ACF-89FA-808FADC55C2E} {A66D48C9-F141-4111-9169-CEB64AFFF61D} = {8AC72641-30D3-4ACF-89FA-808FADC55C2E}
{524276E1-053D-4191-ABF7-4CDA01BFFBC3} = {8AC72641-30D3-4ACF-89FA-808FADC55C2E} {524276E1-053D-4191-ABF7-4CDA01BFFBC3} = {8AC72641-30D3-4ACF-89FA-808FADC55C2E}
{43083268-74DE-4C68-824A-FB0CEC77358D} = {8AC72641-30D3-4ACF-89FA-808FADC55C2E}
{DD9BE9E7-F6BF-4869-BCD2-82F5072BDA21} = {C5CAD011-DF84-4914-939C-0C029DCEF26F}
{BAE74ABC-1096-495F-A624-BEBFBC1896F2} = {DD9BE9E7-F6BF-4869-BCD2-82F5072BDA21}
EndGlobalSection EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {C95FDF91-16F2-4A8B-A4BE-0E62D1B66718} SolutionGuid = {C95FDF91-16F2-4A8B-A4BE-0E62D1B66718}

20
aspnet-core/database/ApiGateway-Init-SqlServer.sql

File diff suppressed because one or more lines are too long

98
aspnet-core/database/ApiGateway-Init.sql

@ -11,7 +11,7 @@
Target Server Version : 80020 Target Server Version : 80020
File Encoding : 65001 File Encoding : 65001
Date: 23/10/2020 19:13:56 Date: 31/10/2020 11:28:59
*/ */
SET NAMES utf8mb4; SET NAMES utf8mb4;
@ -54,7 +54,7 @@ CREATE TABLE `appapigatewayaggregate` (
`Priority` int(0) NULL DEFAULT NULL, `Priority` int(0) NULL DEFAULT NULL,
`UpstreamHttpMethod` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, `UpstreamHttpMethod` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
PRIMARY KEY (`Id`) USING BTREE PRIMARY KEY (`Id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 8 CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic; ) ENGINE = InnoDB AUTO_INCREMENT = 6 CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic;
-- ---------------------------- -- ----------------------------
-- Records of appapigatewayaggregate -- Records of appapigatewayaggregate
@ -76,7 +76,7 @@ CREATE TABLE `appapigatewayaggregateconfig` (
PRIMARY KEY (`Id`) USING BTREE, PRIMARY KEY (`Id`) USING BTREE,
INDEX `IX_AppApiGatewayAggregateConfig_AggregateReRouteId`(`AggregateReRouteId`) USING BTREE, INDEX `IX_AppApiGatewayAggregateConfig_AggregateReRouteId`(`AggregateReRouteId`) USING BTREE,
CONSTRAINT `FK_AppApiGatewayAggregateConfig_AppApiGatewayAggregate_Aggregat~` FOREIGN KEY (`AggregateReRouteId`) REFERENCES `appapigatewayaggregate` (`Id`) ON DELETE RESTRICT ON UPDATE RESTRICT CONSTRAINT `FK_AppApiGatewayAggregateConfig_AppApiGatewayAggregate_Aggregat~` FOREIGN KEY (`AggregateReRouteId`) REFERENCES `appapigatewayaggregate` (`Id`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic; ) ENGINE = InnoDB CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic;
-- ---------------------------- -- ----------------------------
-- Table structure for appapigatewayauthoptions -- Table structure for appapigatewayauthoptions
@ -90,7 +90,7 @@ CREATE TABLE `appapigatewayauthoptions` (
PRIMARY KEY (`Id`) USING BTREE, PRIMARY KEY (`Id`) USING BTREE,
UNIQUE INDEX `IX_AppApiGatewayAuthOptions_ReRouteId`(`ReRouteId`) USING BTREE, UNIQUE INDEX `IX_AppApiGatewayAuthOptions_ReRouteId`(`ReRouteId`) USING BTREE,
CONSTRAINT `FK_AppApiGatewayAuthOptions_AppApiGatewayReRoute_ReRouteId` FOREIGN KEY (`ReRouteId`) REFERENCES `appapigatewayreroute` (`ReRouteId`) ON DELETE CASCADE ON UPDATE RESTRICT CONSTRAINT `FK_AppApiGatewayAuthOptions_AppApiGatewayReRoute_ReRouteId` FOREIGN KEY (`ReRouteId`) REFERENCES `appapigatewayreroute` (`ReRouteId`) ON DELETE CASCADE ON UPDATE RESTRICT
) ENGINE = InnoDB AUTO_INCREMENT = 145 CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic; ) ENGINE = InnoDB AUTO_INCREMENT = 149 CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic;
-- ---------------------------- -- ----------------------------
-- Records of appapigatewayauthoptions -- Records of appapigatewayauthoptions
@ -205,6 +205,11 @@ INSERT INTO `appapigatewayauthoptions` VALUES (141, 1319554948434595840, '', '')
INSERT INTO `appapigatewayauthoptions` VALUES (142, 1319555067183730688, '', ''); INSERT INTO `appapigatewayauthoptions` VALUES (142, 1319555067183730688, '', '');
INSERT INTO `appapigatewayauthoptions` VALUES (143, 1319555230765780992, '', ''); INSERT INTO `appapigatewayauthoptions` VALUES (143, 1319555230765780992, '', '');
INSERT INTO `appapigatewayauthoptions` VALUES (144, 1319555333790470144, '', ''); INSERT INTO `appapigatewayauthoptions` VALUES (144, 1319555333790470144, '', '');
INSERT INTO `appapigatewayauthoptions` VALUES (145, 1321001932510203904, '', '');
INSERT INTO `appapigatewayauthoptions` VALUES (146, 1321002059803136000, '', '');
INSERT INTO `appapigatewayauthoptions` VALUES (147, 1321002256440496128, '', '');
INSERT INTO `appapigatewayauthoptions` VALUES (148, 1321002350686507008, '', '');
INSERT INTO `appapigatewayauthoptions` VALUES (149, 1322190027988525056, '', '');
-- ---------------------------- -- ----------------------------
-- Table structure for appapigatewaybalanceroptions -- Table structure for appapigatewaybalanceroptions
@ -222,7 +227,7 @@ CREATE TABLE `appapigatewaybalanceroptions` (
UNIQUE INDEX `IX_AppApiGatewayBalancerOptions_ReRouteId`(`ReRouteId`) USING BTREE, UNIQUE INDEX `IX_AppApiGatewayBalancerOptions_ReRouteId`(`ReRouteId`) USING BTREE,
CONSTRAINT `FK_AppApiGatewayBalancerOptions_AppApiGatewayGlobalConfiguratio~` FOREIGN KEY (`ItemId`) REFERENCES `appapigatewayglobalconfiguration` (`ItemId`) ON DELETE CASCADE ON UPDATE RESTRICT, CONSTRAINT `FK_AppApiGatewayBalancerOptions_AppApiGatewayGlobalConfiguratio~` FOREIGN KEY (`ItemId`) REFERENCES `appapigatewayglobalconfiguration` (`ItemId`) ON DELETE CASCADE ON UPDATE RESTRICT,
CONSTRAINT `FK_AppApiGatewayBalancerOptions_AppApiGatewayReRoute_ReRouteId` FOREIGN KEY (`ReRouteId`) REFERENCES `appapigatewayreroute` (`ReRouteId`) ON DELETE CASCADE ON UPDATE RESTRICT CONSTRAINT `FK_AppApiGatewayBalancerOptions_AppApiGatewayReRoute_ReRouteId` FOREIGN KEY (`ReRouteId`) REFERENCES `appapigatewayreroute` (`ReRouteId`) ON DELETE CASCADE ON UPDATE RESTRICT
) ENGINE = InnoDB AUTO_INCREMENT = 148 CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic; ) ENGINE = InnoDB AUTO_INCREMENT = 152 CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic;
-- ---------------------------- -- ----------------------------
-- Records of appapigatewaybalanceroptions -- Records of appapigatewaybalanceroptions
@ -338,6 +343,11 @@ INSERT INTO `appapigatewaybalanceroptions` VALUES (144, NULL, 131955494843459584
INSERT INTO `appapigatewaybalanceroptions` VALUES (145, NULL, 1319555067183730688, '', '', 0); INSERT INTO `appapigatewaybalanceroptions` VALUES (145, NULL, 1319555067183730688, '', '', 0);
INSERT INTO `appapigatewaybalanceroptions` VALUES (146, NULL, 1319555230765780992, '', '', 0); INSERT INTO `appapigatewaybalanceroptions` VALUES (146, NULL, 1319555230765780992, '', '', 0);
INSERT INTO `appapigatewaybalanceroptions` VALUES (147, NULL, 1319555333790470144, '', '', 0); INSERT INTO `appapigatewaybalanceroptions` VALUES (147, NULL, 1319555333790470144, '', '', 0);
INSERT INTO `appapigatewaybalanceroptions` VALUES (148, NULL, 1321001932510203904, '', '', 0);
INSERT INTO `appapigatewaybalanceroptions` VALUES (149, NULL, 1321002059803136000, '', '', 0);
INSERT INTO `appapigatewaybalanceroptions` VALUES (150, NULL, 1321002256440496128, '', '', 0);
INSERT INTO `appapigatewaybalanceroptions` VALUES (151, NULL, 1321002350686507008, '', '', 0);
INSERT INTO `appapigatewaybalanceroptions` VALUES (152, NULL, 1322190027988525056, '', '', 0);
-- ---------------------------- -- ----------------------------
-- Table structure for appapigatewaycacheoptions -- Table structure for appapigatewaycacheoptions
@ -351,7 +361,7 @@ CREATE TABLE `appapigatewaycacheoptions` (
PRIMARY KEY (`Id`) USING BTREE, PRIMARY KEY (`Id`) USING BTREE,
UNIQUE INDEX `IX_AppApiGatewayCacheOptions_ReRouteId`(`ReRouteId`) USING BTREE, UNIQUE INDEX `IX_AppApiGatewayCacheOptions_ReRouteId`(`ReRouteId`) USING BTREE,
CONSTRAINT `FK_AppApiGatewayCacheOptions_AppApiGatewayReRoute_ReRouteId` FOREIGN KEY (`ReRouteId`) REFERENCES `appapigatewayreroute` (`ReRouteId`) ON DELETE CASCADE ON UPDATE RESTRICT CONSTRAINT `FK_AppApiGatewayCacheOptions_AppApiGatewayReRoute_ReRouteId` FOREIGN KEY (`ReRouteId`) REFERENCES `appapigatewayreroute` (`ReRouteId`) ON DELETE CASCADE ON UPDATE RESTRICT
) ENGINE = InnoDB AUTO_INCREMENT = 145 CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic; ) ENGINE = InnoDB AUTO_INCREMENT = 149 CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic;
-- ---------------------------- -- ----------------------------
-- Records of appapigatewaycacheoptions -- Records of appapigatewaycacheoptions
@ -466,6 +476,11 @@ INSERT INTO `appapigatewaycacheoptions` VALUES (141, 1319554948434595840, 0, '')
INSERT INTO `appapigatewaycacheoptions` VALUES (142, 1319555067183730688, 0, ''); INSERT INTO `appapigatewaycacheoptions` VALUES (142, 1319555067183730688, 0, '');
INSERT INTO `appapigatewaycacheoptions` VALUES (143, 1319555230765780992, 0, ''); INSERT INTO `appapigatewaycacheoptions` VALUES (143, 1319555230765780992, 0, '');
INSERT INTO `appapigatewaycacheoptions` VALUES (144, 1319555333790470144, 0, ''); INSERT INTO `appapigatewaycacheoptions` VALUES (144, 1319555333790470144, 0, '');
INSERT INTO `appapigatewaycacheoptions` VALUES (145, 1321001932510203904, 0, '');
INSERT INTO `appapigatewaycacheoptions` VALUES (146, 1321002059803136000, 0, '');
INSERT INTO `appapigatewaycacheoptions` VALUES (147, 1321002256440496128, 0, '');
INSERT INTO `appapigatewaycacheoptions` VALUES (148, 1321002350686507008, 0, '');
INSERT INTO `appapigatewaycacheoptions` VALUES (149, 1322190027988525056, 0, '');
-- ---------------------------- -- ----------------------------
-- Table structure for appapigatewaydiscovery -- Table structure for appapigatewaydiscovery
@ -485,7 +500,7 @@ CREATE TABLE `appapigatewaydiscovery` (
PRIMARY KEY (`Id`) USING BTREE, PRIMARY KEY (`Id`) USING BTREE,
UNIQUE INDEX `IX_AppApiGatewayDiscovery_ItemId`(`ItemId`) USING BTREE, UNIQUE INDEX `IX_AppApiGatewayDiscovery_ItemId`(`ItemId`) USING BTREE,
CONSTRAINT `FK_AppApiGatewayDiscovery_AppApiGatewayGlobalConfiguration_Item~` FOREIGN KEY (`ItemId`) REFERENCES `appapigatewayglobalconfiguration` (`ItemId`) ON DELETE CASCADE ON UPDATE RESTRICT CONSTRAINT `FK_AppApiGatewayDiscovery_AppApiGatewayGlobalConfiguration_Item~` FOREIGN KEY (`ItemId`) REFERENCES `appapigatewayglobalconfiguration` (`ItemId`) ON DELETE CASCADE ON UPDATE RESTRICT
) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic; ) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic;
-- ---------------------------- -- ----------------------------
-- Records of appapigatewaydiscovery -- Records of appapigatewaydiscovery
@ -506,7 +521,7 @@ CREATE TABLE `appapigatewaydynamicreroute` (
`AppId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `AppId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
PRIMARY KEY (`Id`) USING BTREE, PRIMARY KEY (`Id`) USING BTREE,
UNIQUE INDEX `AK_AppApiGatewayDynamicReRoute_DynamicReRouteId`(`DynamicReRouteId`) USING BTREE UNIQUE INDEX `AK_AppApiGatewayDynamicReRoute_DynamicReRouteId`(`DynamicReRouteId`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic; ) ENGINE = InnoDB CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic;
-- ---------------------------- -- ----------------------------
-- Table structure for appapigatewayglobalconfiguration -- Table structure for appapigatewayglobalconfiguration
@ -526,7 +541,7 @@ CREATE TABLE `appapigatewayglobalconfiguration` (
`AppId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `AppId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
PRIMARY KEY (`Id`) USING BTREE, PRIMARY KEY (`Id`) USING BTREE,
UNIQUE INDEX `AK_AppApiGatewayGlobalConfiguration_ItemId`(`ItemId`) USING BTREE UNIQUE INDEX `AK_AppApiGatewayGlobalConfiguration_ItemId`(`ItemId`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic; ) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic;
-- ---------------------------- -- ----------------------------
-- Records of appapigatewayglobalconfiguration -- Records of appapigatewayglobalconfiguration
@ -543,7 +558,7 @@ CREATE TABLE `appapigatewayheaders` (
`Key` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, `Key` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
`Value` varchar(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, `Value` varchar(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
PRIMARY KEY (`Id`) USING BTREE PRIMARY KEY (`Id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic; ) ENGINE = InnoDB CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic;
-- ---------------------------- -- ----------------------------
-- Table structure for appapigatewayhostandport -- Table structure for appapigatewayhostandport
@ -555,7 +570,7 @@ CREATE TABLE `appapigatewayhostandport` (
`Host` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `Host` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
`Port` int(0) NULL DEFAULT 0, `Port` int(0) NULL DEFAULT 0,
PRIMARY KEY (`Id`) USING BTREE PRIMARY KEY (`Id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic; ) ENGINE = InnoDB CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic;
-- ---------------------------- -- ----------------------------
-- Table structure for appapigatewayhttpoptions -- Table structure for appapigatewayhttpoptions
@ -575,7 +590,7 @@ CREATE TABLE `appapigatewayhttpoptions` (
UNIQUE INDEX `IX_AppApiGatewayHttpOptions_ReRouteId`(`ReRouteId`) USING BTREE, UNIQUE INDEX `IX_AppApiGatewayHttpOptions_ReRouteId`(`ReRouteId`) USING BTREE,
CONSTRAINT `FK_AppApiGatewayHttpOptions_AppApiGatewayGlobalConfiguration_It~` FOREIGN KEY (`ItemId`) REFERENCES `appapigatewayglobalconfiguration` (`ItemId`) ON DELETE CASCADE ON UPDATE RESTRICT, CONSTRAINT `FK_AppApiGatewayHttpOptions_AppApiGatewayGlobalConfiguration_It~` FOREIGN KEY (`ItemId`) REFERENCES `appapigatewayglobalconfiguration` (`ItemId`) ON DELETE CASCADE ON UPDATE RESTRICT,
CONSTRAINT `FK_AppApiGatewayHttpOptions_AppApiGatewayReRoute_ReRouteId` FOREIGN KEY (`ReRouteId`) REFERENCES `appapigatewayreroute` (`ReRouteId`) ON DELETE CASCADE ON UPDATE RESTRICT CONSTRAINT `FK_AppApiGatewayHttpOptions_AppApiGatewayReRoute_ReRouteId` FOREIGN KEY (`ReRouteId`) REFERENCES `appapigatewayreroute` (`ReRouteId`) ON DELETE CASCADE ON UPDATE RESTRICT
) ENGINE = InnoDB AUTO_INCREMENT = 148 CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic; ) ENGINE = InnoDB AUTO_INCREMENT = 152 CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic;
-- ---------------------------- -- ----------------------------
-- Records of appapigatewayhttpoptions -- Records of appapigatewayhttpoptions
@ -691,6 +706,11 @@ INSERT INTO `appapigatewayhttpoptions` VALUES (144, NULL, 1319554948434595840, 0
INSERT INTO `appapigatewayhttpoptions` VALUES (145, NULL, 1319555067183730688, 0, 0, 0, 0, 0); INSERT INTO `appapigatewayhttpoptions` VALUES (145, NULL, 1319555067183730688, 0, 0, 0, 0, 0);
INSERT INTO `appapigatewayhttpoptions` VALUES (146, NULL, 1319555230765780992, 0, 0, 0, 0, 0); INSERT INTO `appapigatewayhttpoptions` VALUES (146, NULL, 1319555230765780992, 0, 0, 0, 0, 0);
INSERT INTO `appapigatewayhttpoptions` VALUES (147, NULL, 1319555333790470144, 0, 0, 0, 0, 0); INSERT INTO `appapigatewayhttpoptions` VALUES (147, NULL, 1319555333790470144, 0, 0, 0, 0, 0);
INSERT INTO `appapigatewayhttpoptions` VALUES (148, NULL, 1321001932510203904, 0, 0, 0, 0, 0);
INSERT INTO `appapigatewayhttpoptions` VALUES (149, NULL, 1321002059803136000, 0, 0, 0, 0, 0);
INSERT INTO `appapigatewayhttpoptions` VALUES (150, NULL, 1321002256440496128, 0, 0, 0, 0, 0);
INSERT INTO `appapigatewayhttpoptions` VALUES (151, NULL, 1321002350686507008, 0, 0, 0, 0, 0);
INSERT INTO `appapigatewayhttpoptions` VALUES (152, NULL, 1322190027988525056, 0, 0, 0, 0, 0);
-- ---------------------------- -- ----------------------------
-- Table structure for appapigatewayqosoptions -- Table structure for appapigatewayqosoptions
@ -708,7 +728,7 @@ CREATE TABLE `appapigatewayqosoptions` (
UNIQUE INDEX `IX_AppApiGatewayQoSOptions_ReRouteId`(`ReRouteId`) USING BTREE, UNIQUE INDEX `IX_AppApiGatewayQoSOptions_ReRouteId`(`ReRouteId`) USING BTREE,
CONSTRAINT `FK_AppApiGatewayQoSOptions_AppApiGatewayGlobalConfiguration_Ite~` FOREIGN KEY (`ItemId`) REFERENCES `appapigatewayglobalconfiguration` (`ItemId`) ON DELETE CASCADE ON UPDATE RESTRICT, CONSTRAINT `FK_AppApiGatewayQoSOptions_AppApiGatewayGlobalConfiguration_Ite~` FOREIGN KEY (`ItemId`) REFERENCES `appapigatewayglobalconfiguration` (`ItemId`) ON DELETE CASCADE ON UPDATE RESTRICT,
CONSTRAINT `FK_AppApiGatewayQoSOptions_AppApiGatewayReRoute_ReRouteId` FOREIGN KEY (`ReRouteId`) REFERENCES `appapigatewayreroute` (`ReRouteId`) ON DELETE CASCADE ON UPDATE RESTRICT CONSTRAINT `FK_AppApiGatewayQoSOptions_AppApiGatewayReRoute_ReRouteId` FOREIGN KEY (`ReRouteId`) REFERENCES `appapigatewayreroute` (`ReRouteId`) ON DELETE CASCADE ON UPDATE RESTRICT
) ENGINE = InnoDB AUTO_INCREMENT = 148 CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic; ) ENGINE = InnoDB AUTO_INCREMENT = 152 CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic;
-- ---------------------------- -- ----------------------------
-- Records of appapigatewayqosoptions -- Records of appapigatewayqosoptions
@ -824,6 +844,11 @@ INSERT INTO `appapigatewayqosoptions` VALUES (144, NULL, 1319554948434595840, 50
INSERT INTO `appapigatewayqosoptions` VALUES (145, NULL, 1319555067183730688, 50, 60000, 30000); INSERT INTO `appapigatewayqosoptions` VALUES (145, NULL, 1319555067183730688, 50, 60000, 30000);
INSERT INTO `appapigatewayqosoptions` VALUES (146, NULL, 1319555230765780992, 50, 60000, 30000); INSERT INTO `appapigatewayqosoptions` VALUES (146, NULL, 1319555230765780992, 50, 60000, 30000);
INSERT INTO `appapigatewayqosoptions` VALUES (147, NULL, 1319555333790470144, 50, 60000, 30000); INSERT INTO `appapigatewayqosoptions` VALUES (147, NULL, 1319555333790470144, 50, 60000, 30000);
INSERT INTO `appapigatewayqosoptions` VALUES (148, NULL, 1321001932510203904, 50, 60000, 30000);
INSERT INTO `appapigatewayqosoptions` VALUES (149, NULL, 1321002059803136000, 50, 60000, 30000);
INSERT INTO `appapigatewayqosoptions` VALUES (150, NULL, 1321002256440496128, 50, 60000, 30000);
INSERT INTO `appapigatewayqosoptions` VALUES (151, NULL, 1321002350686507008, 50, 60000, 30000);
INSERT INTO `appapigatewayqosoptions` VALUES (152, NULL, 1322190027988525056, 50, 60000, 30000);
-- ---------------------------- -- ----------------------------
-- Table structure for appapigatewayratelimitoptions -- Table structure for appapigatewayratelimitoptions
@ -840,7 +865,7 @@ CREATE TABLE `appapigatewayratelimitoptions` (
PRIMARY KEY (`Id`) USING BTREE, PRIMARY KEY (`Id`) USING BTREE,
UNIQUE INDEX `IX_AppApiGatewayRateLimitOptions_ItemId`(`ItemId`) USING BTREE, UNIQUE INDEX `IX_AppApiGatewayRateLimitOptions_ItemId`(`ItemId`) USING BTREE,
CONSTRAINT `FK_AppApiGatewayRateLimitOptions_AppApiGatewayGlobalConfigurati~` FOREIGN KEY (`ItemId`) REFERENCES `appapigatewayglobalconfiguration` (`ItemId`) ON DELETE CASCADE ON UPDATE RESTRICT CONSTRAINT `FK_AppApiGatewayRateLimitOptions_AppApiGatewayGlobalConfigurati~` FOREIGN KEY (`ItemId`) REFERENCES `appapigatewayglobalconfiguration` (`ItemId`) ON DELETE CASCADE ON UPDATE RESTRICT
) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic; ) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic;
-- ---------------------------- -- ----------------------------
-- Records of appapigatewayratelimitoptions -- Records of appapigatewayratelimitoptions
@ -865,7 +890,7 @@ CREATE TABLE `appapigatewayratelimitrule` (
UNIQUE INDEX `IX_AppApiGatewayRateLimitRule_ReRouteId`(`ReRouteId`) USING BTREE, UNIQUE INDEX `IX_AppApiGatewayRateLimitRule_ReRouteId`(`ReRouteId`) USING BTREE,
CONSTRAINT `FK_AppApiGatewayRateLimitRule_AppApiGatewayDynamicReRoute_Dynam~` FOREIGN KEY (`DynamicReRouteId`) REFERENCES `appapigatewaydynamicreroute` (`DynamicReRouteId`) ON DELETE CASCADE ON UPDATE RESTRICT, CONSTRAINT `FK_AppApiGatewayRateLimitRule_AppApiGatewayDynamicReRoute_Dynam~` FOREIGN KEY (`DynamicReRouteId`) REFERENCES `appapigatewaydynamicreroute` (`DynamicReRouteId`) ON DELETE CASCADE ON UPDATE RESTRICT,
CONSTRAINT `FK_AppApiGatewayRateLimitRule_AppApiGatewayReRoute_ReRouteId` FOREIGN KEY (`ReRouteId`) REFERENCES `appapigatewayreroute` (`ReRouteId`) ON DELETE CASCADE ON UPDATE RESTRICT CONSTRAINT `FK_AppApiGatewayRateLimitRule_AppApiGatewayReRoute_ReRouteId` FOREIGN KEY (`ReRouteId`) REFERENCES `appapigatewayreroute` (`ReRouteId`) ON DELETE CASCADE ON UPDATE RESTRICT
) ENGINE = InnoDB AUTO_INCREMENT = 145 CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic; ) ENGINE = InnoDB AUTO_INCREMENT = 149 CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic;
-- ---------------------------- -- ----------------------------
-- Records of appapigatewayratelimitrule -- Records of appapigatewayratelimitrule
@ -980,6 +1005,11 @@ INSERT INTO `appapigatewayratelimitrule` VALUES (141, 1319554948434595840, NULL,
INSERT INTO `appapigatewayratelimitrule` VALUES (142, 1319555067183730688, NULL, '', 0, NULL, NULL, NULL); INSERT INTO `appapigatewayratelimitrule` VALUES (142, 1319555067183730688, NULL, '', 0, NULL, NULL, NULL);
INSERT INTO `appapigatewayratelimitrule` VALUES (143, 1319555230765780992, NULL, '', 0, NULL, NULL, NULL); INSERT INTO `appapigatewayratelimitrule` VALUES (143, 1319555230765780992, NULL, '', 0, NULL, NULL, NULL);
INSERT INTO `appapigatewayratelimitrule` VALUES (144, 1319555333790470144, NULL, '', 0, NULL, NULL, NULL); INSERT INTO `appapigatewayratelimitrule` VALUES (144, 1319555333790470144, NULL, '', 0, NULL, NULL, NULL);
INSERT INTO `appapigatewayratelimitrule` VALUES (145, 1321001932510203904, NULL, '', 0, NULL, NULL, NULL);
INSERT INTO `appapigatewayratelimitrule` VALUES (146, 1321002059803136000, NULL, '', 0, NULL, NULL, NULL);
INSERT INTO `appapigatewayratelimitrule` VALUES (147, 1321002256440496128, NULL, '', 0, NULL, NULL, NULL);
INSERT INTO `appapigatewayratelimitrule` VALUES (148, 1321002350686507008, NULL, '', 0, NULL, NULL, NULL);
INSERT INTO `appapigatewayratelimitrule` VALUES (149, 1322190027988525056, NULL, '', 0, NULL, NULL, NULL);
-- ---------------------------- -- ----------------------------
-- Table structure for appapigatewayreroute -- Table structure for appapigatewayreroute
@ -1019,7 +1049,7 @@ CREATE TABLE `appapigatewayreroute` (
PRIMARY KEY (`Id`) USING BTREE, PRIMARY KEY (`Id`) USING BTREE,
UNIQUE INDEX `AK_AppApiGatewayReRoute_ReRouteId`(`ReRouteId`) USING BTREE, UNIQUE INDEX `AK_AppApiGatewayReRoute_ReRouteId`(`ReRouteId`) USING BTREE,
UNIQUE INDEX `IX_AppApiGatewayReRoute_AppId_DownstreamPathTemplate_UpstreamPa~`(`AppId`, `DownstreamPathTemplate`, `UpstreamPathTemplate`) USING BTREE UNIQUE INDEX `IX_AppApiGatewayReRoute_AppId_DownstreamPathTemplate_UpstreamPa~`(`AppId`, `DownstreamPathTemplate`, `UpstreamPathTemplate`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 152 CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic; ) ENGINE = InnoDB AUTO_INCREMENT = 156 CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic;
-- ---------------------------- -- ----------------------------
-- Records of appapigatewayreroute -- Records of appapigatewayreroute
@ -1081,8 +1111,8 @@ INSERT INTO `appapigatewayreroute` VALUES (67, '{}', '755b4dce5c34444785fa3b647f
INSERT INTO `appapigatewayreroute` VALUES (68, '{}', '535191c570ae453ab320012304d7a62c', 1264800070161584128, '【身份认证服务】- 手机号注册', '/api/account/phone/register', '', '', '/api/account/phone/register', 'POST,', '', '', '', '', '', '', '', 1, '', '', 'HTTP', '127.0.0.1:30015,', '', '', '', 0, 30000, 1, '', 'TEST-APP'); INSERT INTO `appapigatewayreroute` VALUES (68, '{}', '535191c570ae453ab320012304d7a62c', 1264800070161584128, '【身份认证服务】- 手机号注册', '/api/account/phone/register', '', '', '/api/account/phone/register', 'POST,', '', '', '', '', '', '', '', 1, '', '', 'HTTP', '127.0.0.1:30015,', '', '', '', 0, 30000, 1, '', 'TEST-APP');
INSERT INTO `appapigatewayreroute` VALUES (69, '{}', '723c9b111f9f4a1aa804118cdde193d3', 1267360794414161920, '【消息服务】- 通知', '/signalr-hubs/notifications/{everything}', '', '', '/signalr-hubs/notifications/{everything}', 'POST,GET,OPTIONS,PUT,DELETE,', '', '', '', '', '', '', '', 1, '', '', 'ws', '127.0.0.1:30020,', '', '', '', 1, 30000, 1, '', 'TEST-APP'); INSERT INTO `appapigatewayreroute` VALUES (69, '{}', '723c9b111f9f4a1aa804118cdde193d3', 1267360794414161920, '【消息服务】- 通知', '/signalr-hubs/notifications/{everything}', '', '', '/signalr-hubs/notifications/{everything}', 'POST,GET,OPTIONS,PUT,DELETE,', '', '', '', '', '', '', '', 1, '', '', 'ws', '127.0.0.1:30020,', '', '', '', 1, 30000, 1, '', 'TEST-APP');
INSERT INTO `appapigatewayreroute` VALUES (70, '{}', 'f3aa2b42dd9f468aa5aae4ef64754427', 1267383367629807616, '【消息服务】- 通知0', '/signalr-hubs/notifications', '', '', '/signalr-hubs/notifications', 'GET,POST,PUT,DELETE,OPTIONS,', '', '', '', '', '', '', '', 1, '', '', 'ws', '127.0.0.1:30020,', '', '', '', 0, 30000, 1, '', 'TEST-APP'); INSERT INTO `appapigatewayreroute` VALUES (70, '{}', 'f3aa2b42dd9f468aa5aae4ef64754427', 1267383367629807616, '【消息服务】- 通知0', '/signalr-hubs/notifications', '', '', '/signalr-hubs/notifications', 'GET,POST,PUT,DELETE,OPTIONS,', '', '', '', '', '', '', '', 1, '', '', 'ws', '127.0.0.1:30020,', '', '', '', 0, 30000, 1, '', 'TEST-APP');
INSERT INTO `appapigatewayreroute` VALUES (71, '{}', '99dc8259c50044008c8aede7442ddde3', 1267817055527632896, '【消息服务】- 聊天', '/signalr-hubs/message', '', '', '/signalr-hubs/message', 'GET,POST,PUT,DELETE,OPTIONS,', '', '', '', '', '', '', '', 1, '', '', 'ws', '127.0.0.1:30020,', '', '', '', 1, 30000, 1, '', 'TEST-APP'); INSERT INTO `appapigatewayreroute` VALUES (71, '{}', '0344947bb79b401baa2ef7b4e58297f6', 1267817055527632896, '【消息服务】- 聊天', '/signalr-hubs/messages', '', '', '/signalr-hubs/messages', 'GET,POST,PUT,DELETE,OPTIONS,', '', '', '', '', '', '', '', 1, '', '', 'ws', '127.0.0.1:30020,', '', '', '', 1, 30000, 1, '', 'TEST-APP');
INSERT INTO `appapigatewayreroute` VALUES (72, '{}', '4ec40b72d469474ba10ae02e8d3298bb', 1267817221286526976, '【消息服务】- 聊天1', '/signalr-hubs/message/{everything}', '', '', '/signalr-hubs/message/{everything}', 'GET,POST,PUT,DELETE,OPTIONS,', '', '', '', '', '', '', '', 1, '', '', 'ws', '127.0.0.1:30020,', '', '', '', 0, 30000, 1, '', 'TEST-APP'); INSERT INTO `appapigatewayreroute` VALUES (72, '{}', '6676b5e5f76d40739f9ccc3e371e2f18', 1267817221286526976, '【消息服务】- 聊天1', '/signalr-hubs/messages/{everything}', '', '', '/signalr-hubs/messages/{everything}', 'GET,POST,PUT,DELETE,OPTIONS,', '', '', '', '', '', '', '', 1, '', '', 'ws', '127.0.0.1:30020,', '', '', '', 0, 30000, 1, '', 'TEST-APP');
INSERT INTO `appapigatewayreroute` VALUES (73, '{}', 'cfb5f09a12bf495fbcaf2fa5d9123a40', 1268893687085518848, '【身份认证服务】- 重置密码', '/api/account/phone/reset-password', '', '', '/api/account/phone/reset-password', 'PUT,', '', '', '', '', '', '', '', 1, '', '', 'HTTP', '127.0.0.1:30015,', '', '', '', 1, 30000, 1, '', 'TEST-APP'); INSERT INTO `appapigatewayreroute` VALUES (73, '{}', 'cfb5f09a12bf495fbcaf2fa5d9123a40', 1268893687085518848, '【身份认证服务】- 重置密码', '/api/account/phone/reset-password', '', '', '/api/account/phone/reset-password', 'PUT,', '', '', '', '', '', '', '', 1, '', '', 'HTTP', '127.0.0.1:30015,', '', '', '', 1, 30000, 1, '', 'TEST-APP');
INSERT INTO `appapigatewayreroute` VALUES (101, '{}', '997a4c27a433458aafed9b8aa252d957', 1288657613998579712, '【身份认证服务】- 组织机构列表', '/api/identity/organization-units', '', '', '/api/identity/organization-units', 'GET,POST,', '', '', '', '', '', '', '', 1, '', '', 'HTTP', '127.0.0.1:30015,', '', '', '', 0, 30000, 1, '', 'TEST-APP'); INSERT INTO `appapigatewayreroute` VALUES (101, '{}', '997a4c27a433458aafed9b8aa252d957', 1288657613998579712, '【身份认证服务】- 组织机构列表', '/api/identity/organization-units', '', '', '/api/identity/organization-units', 'GET,POST,', '', '', '', '', '', '', '', 1, '', '', 'HTTP', '127.0.0.1:30015,', '', '', '', 0, 30000, 1, '', 'TEST-APP');
INSERT INTO `appapigatewayreroute` VALUES (102, '{}', 'a2c6acc9882a425ab26bd3ad5a9c17c6', 1288657941770854400, '【身份认证服务】- 组织机构管理', '/api/identity/organization-units/{id}', '', '', '/api/identity/organization-units/{id}', 'GET,PUT,DELETE,', '', '', '', '', '', '', '', 1, '', '', 'HTTP', '127.0.0.1:30015,', '', '', '', 1, 30000, 1, '', 'TEST-APP'); INSERT INTO `appapigatewayreroute` VALUES (102, '{}', 'a2c6acc9882a425ab26bd3ad5a9c17c6', 1288657941770854400, '【身份认证服务】- 组织机构管理', '/api/identity/organization-units/{id}', '', '', '/api/identity/organization-units/{id}', 'GET,PUT,DELETE,', '', '', '', '', '', '', '', 1, '', '', 'HTTP', '127.0.0.1:30015,', '', '', '', 1, 30000, 1, '', 'TEST-APP');
@ -1134,6 +1164,11 @@ INSERT INTO `appapigatewayreroute` VALUES (148, '{}', '824f5eee6877489f96f1022e3
INSERT INTO `appapigatewayreroute` VALUES (149, '{}', 'fe1379d4a13f41afb6410f4c948871f3', 1319555067183730688, '【身份认证服务】- 删除角色组织机构', '/api/identity/roles/{id}/organization-units/{ouId}', '', '', '/api/identity/roles/{id}/organization-units/{ouId}', 'DELETE,', '', '', '', '', '', '', '', 1, '', '', 'HTTP', '127.0.0.1:30015,', '', '', '', 0, 30000, 1, '', 'TEST-APP'); INSERT INTO `appapigatewayreroute` VALUES (149, '{}', 'fe1379d4a13f41afb6410f4c948871f3', 1319555067183730688, '【身份认证服务】- 删除角色组织机构', '/api/identity/roles/{id}/organization-units/{ouId}', '', '', '/api/identity/roles/{id}/organization-units/{ouId}', 'DELETE,', '', '', '', '', '', '', '', 1, '', '', 'HTTP', '127.0.0.1:30015,', '', '', '', 0, 30000, 1, '', 'TEST-APP');
INSERT INTO `appapigatewayreroute` VALUES (150, '{}', '197a69bb723346aba3601bd61e7fa655', 1319555230765780992, '【身份认证服务】- 管理用户组织机构', '/api/identity/users/{id}/organization-units', '', '', '/api/identity/users/{id}/organization-units', 'GET,PUT,', '', '', '', '', '', '', '', 1, '', '', 'HTTP', '127.0.0.1:30015,', '', '', '', 0, 30000, 1, '', 'TEST-APP'); INSERT INTO `appapigatewayreroute` VALUES (150, '{}', '197a69bb723346aba3601bd61e7fa655', 1319555230765780992, '【身份认证服务】- 管理用户组织机构', '/api/identity/users/{id}/organization-units', '', '', '/api/identity/users/{id}/organization-units', 'GET,PUT,', '', '', '', '', '', '', '', 1, '', '', 'HTTP', '127.0.0.1:30015,', '', '', '', 0, 30000, 1, '', 'TEST-APP');
INSERT INTO `appapigatewayreroute` VALUES (151, '{}', '1a7e6d0b1c95484f82a75a2ce6e6f453', 1319555333790470144, '【身份认证服务】- 删除用户组织机构', '/api/identity/users/{id}/organization-units/{ouId}', '', '', '/api/identity/users/{id}/organization-units/{ouId}', 'DELETE,', '', '', '', '', '', '', '', 1, '', '', 'HTTP', '127.0.0.1:30015,', '', '', '', 0, 30000, 1, '', 'TEST-APP'); INSERT INTO `appapigatewayreroute` VALUES (151, '{}', '1a7e6d0b1c95484f82a75a2ce6e6f453', 1319555333790470144, '【身份认证服务】- 删除用户组织机构', '/api/identity/users/{id}/organization-units/{ouId}', '', '', '/api/identity/users/{id}/organization-units/{ouId}', 'DELETE,', '', '', '', '', '', '', '', 1, '', '', 'HTTP', '127.0.0.1:30015,', '', '', '', 0, 30000, 1, '', 'TEST-APP');
INSERT INTO `appapigatewayreroute` VALUES (152, '{}', 'ecfa9bbd19694097b33e691b653f2124', 1321001932510203904, '【消息服务】- 我的消息', '/api/im/chat/my-messages', '', '', '/api/im/chat/my-messages', 'GET,', '', '', '', '', '', '', '', 1, '', '', 'HTTP', '127.0.0.1:30020,', '', '', '', 0, 30000, 1, '', 'TEST-APP');
INSERT INTO `appapigatewayreroute` VALUES (153, '{}', '4867ad188ca54acb8b961d20297b6545', 1321002059803136000, '【消息服务】- 我的最近消息', '/api/im/chat/my-last-messages', '', '', '/api/im/chat/my-last-messages', 'GET,', '', '', '', '', '', '', '', 1, '', '', 'HTTP', '127.0.0.1:30020,', '', '', '', 0, 30000, 1, '', 'TEST-APP');
INSERT INTO `appapigatewayreroute` VALUES (154, '{}', '291ab802d7bc4af98fc15c509f98fa75', 1321002256440496128, '【消息服务】- 我的朋友', '/api/im/my-friends', '', '', '/api/im/my-friends', 'GET,POST,DELETE,', '', '', '', '', '', '', '', 1, '', '', 'HTTP', '127.0.0.1:30020,', '', '', '', 0, 30000, 1, '', 'TEST-APP');
INSERT INTO `appapigatewayreroute` VALUES (155, '{}', '08438dabb1e849988e0c304f82b08a10', 1321002350686507008, '【消息服务】- 我的所有朋友', '/api/im/my-friends/all', '', '', '/api/im/my-friends/all', 'GET,', '', '', '', '', '', '', '', 1, '', '', 'HTTP', '127.0.0.1:30020,', '', '', '', 0, 30000, 1, '', 'TEST-APP');
INSERT INTO `appapigatewayreroute` VALUES (156, '{}', 'cecf632785b7402299764698369c751f', 1322190027988525056, '【消息服务】- 发送好友请求', '/api/im/my-friends/add-request', '', '', '/api/im/my-friends/add-request', 'POST,', '', '', '', '', '', '', '', 1, '', '', 'HTTP', '127.0.0.1:30020,', '', '', '', 0, 30000, 1, '', 'TEST-APP');
-- ---------------------------- -- ----------------------------
-- Table structure for appapigatewayroutegroup -- Table structure for appapigatewayroutegroup
@ -1177,7 +1212,7 @@ CREATE TABLE `appapigatewaysecurityoptions` (
PRIMARY KEY (`Id`) USING BTREE, PRIMARY KEY (`Id`) USING BTREE,
UNIQUE INDEX `IX_AppApiGatewaySecurityOptions_ReRouteId`(`ReRouteId`) USING BTREE, UNIQUE INDEX `IX_AppApiGatewaySecurityOptions_ReRouteId`(`ReRouteId`) USING BTREE,
CONSTRAINT `FK_AppApiGatewaySecurityOptions_AppApiGatewayReRoute_ReRouteId` FOREIGN KEY (`ReRouteId`) REFERENCES `appapigatewayreroute` (`ReRouteId`) ON DELETE CASCADE ON UPDATE RESTRICT CONSTRAINT `FK_AppApiGatewaySecurityOptions_AppApiGatewayReRoute_ReRouteId` FOREIGN KEY (`ReRouteId`) REFERENCES `appapigatewayreroute` (`ReRouteId`) ON DELETE CASCADE ON UPDATE RESTRICT
) ENGINE = InnoDB AUTO_INCREMENT = 145 CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic; ) ENGINE = InnoDB AUTO_INCREMENT = 149 CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic;
-- ---------------------------- -- ----------------------------
-- Records of appapigatewaysecurityoptions -- Records of appapigatewaysecurityoptions
@ -1292,6 +1327,11 @@ INSERT INTO `appapigatewaysecurityoptions` VALUES (141, 1319554948434595840, '',
INSERT INTO `appapigatewaysecurityoptions` VALUES (142, 1319555067183730688, '', ''); INSERT INTO `appapigatewaysecurityoptions` VALUES (142, 1319555067183730688, '', '');
INSERT INTO `appapigatewaysecurityoptions` VALUES (143, 1319555230765780992, '', ''); INSERT INTO `appapigatewaysecurityoptions` VALUES (143, 1319555230765780992, '', '');
INSERT INTO `appapigatewaysecurityoptions` VALUES (144, 1319555333790470144, '', ''); INSERT INTO `appapigatewaysecurityoptions` VALUES (144, 1319555333790470144, '', '');
INSERT INTO `appapigatewaysecurityoptions` VALUES (145, 1321001932510203904, '', '');
INSERT INTO `appapigatewaysecurityoptions` VALUES (146, 1321002059803136000, '', '');
INSERT INTO `appapigatewaysecurityoptions` VALUES (147, 1321002256440496128, '', '');
INSERT INTO `appapigatewaysecurityoptions` VALUES (148, 1321002350686507008, '', '');
INSERT INTO `appapigatewaysecurityoptions` VALUES (149, 1322190027988525056, '', '');
-- ---------------------------- -- ----------------------------
-- Table structure for cap.published -- Table structure for cap.published
@ -1313,25 +1353,7 @@ CREATE TABLE `cap.published` (
-- ---------------------------- -- ----------------------------
-- Records of cap.published -- Records of cap.published
-- ---------------------------- -- ----------------------------
INSERT INTO `cap.published` VALUES (1319249373444280320, 'v1', 'LINGYUN.ApiGateway.EventBus.ApigatewayConfigChangeEventData', '{\"Headers\":{\"cap-callback-name\":null,\"cap-msg-id\":\"1319249373444280320\",\"cap-msg-name\":\"LINGYUN.ApiGateway.EventBus.ApigatewayConfigChangeEventData\",\"cap-msg-type\":\"Object\",\"cap-senttime\":\"2020/10/22 20:08:55 +08:00\",\"cap-corr-id\":\"1319249373444280320\",\"cap-corr-seq\":\"0\"},\"Value\":{\"DateTime\":\"2020-10-22T20:08:55.7543668+08:00\",\"AppId\":\"TEST-APP\",\"Method\":\"Modify\",\"Object\":\"ReRoute\"}}', 0, '2020-10-22 20:08:56', '2020-10-23 20:08:56', 'Succeeded'); INSERT INTO `cap.published` VALUES (1322190029573971968, 'v1', 'LINGYUN.ApiGateway.EventBus.ApigatewayConfigChangeEventData', '{\"Headers\":{\"cap-callback-name\":null,\"cap-msg-id\":\"1322190029573971968\",\"cap-msg-name\":\"LINGYUN.ApiGateway.EventBus.ApigatewayConfigChangeEventData\",\"cap-msg-type\":\"Object\",\"cap-senttime\":\"2020/10/30 22:54:02 +08:00\",\"cap-corr-id\":\"1322190029573971968\",\"cap-corr-seq\":\"0\"},\"Value\":{\"DateTime\":\"2020-10-30T22:54:02.8070185+08:00\",\"AppId\":\"TEST-APP\",\"Method\":\"Create\",\"Object\":\"ReRoute\"}}', 0, '2020-10-30 22:54:03', '2020-10-31 22:54:03', 'Succeeded');
INSERT INTO `cap.published` VALUES (1319249405602009088, 'v1', 'LINGYUN.ApiGateway.EventBus.ApigatewayConfigChangeEventData', '{\"Headers\":{\"cap-callback-name\":null,\"cap-msg-id\":\"1319249405602009088\",\"cap-msg-name\":\"LINGYUN.ApiGateway.EventBus.ApigatewayConfigChangeEventData\",\"cap-msg-type\":\"Object\",\"cap-senttime\":\"2020/10/22 20:09:03 +08:00\",\"cap-corr-id\":\"1319249405602009088\",\"cap-corr-seq\":\"0\"},\"Value\":{\"DateTime\":\"2020-10-22T20:09:03.4203308+08:00\",\"AppId\":\"TEST-APP\",\"Method\":\"Modify\",\"Object\":\"ReRoute\"}}', 0, '2020-10-22 20:09:03', '2020-10-23 20:09:03', 'Succeeded');
INSERT INTO `cap.published` VALUES (1319249482190000128, 'v1', 'LINGYUN.ApiGateway.EventBus.ApigatewayConfigChangeEventData', '{\"Headers\":{\"cap-callback-name\":null,\"cap-msg-id\":\"1319249482190000128\",\"cap-msg-name\":\"LINGYUN.ApiGateway.EventBus.ApigatewayConfigChangeEventData\",\"cap-msg-type\":\"Object\",\"cap-senttime\":\"2020/10/22 20:09:21 +08:00\",\"cap-corr-id\":\"1319249482190000128\",\"cap-corr-seq\":\"0\"},\"Value\":{\"DateTime\":\"2020-10-22T20:09:21.681402+08:00\",\"AppId\":\"TEST-APP\",\"Method\":\"Modify\",\"Object\":\"ReRoute\"}}', 0, '2020-10-22 20:09:22', '2020-10-23 20:09:22', 'Succeeded');
INSERT INTO `cap.published` VALUES (1319249848986079232, 'v1', 'LINGYUN.ApiGateway.EventBus.ApigatewayConfigChangeEventData', '{\"Headers\":{\"cap-callback-name\":null,\"cap-msg-id\":\"1319249848986079232\",\"cap-msg-name\":\"LINGYUN.ApiGateway.EventBus.ApigatewayConfigChangeEventData\",\"cap-msg-type\":\"Object\",\"cap-senttime\":\"2020/10/22 20:10:49 +08:00\",\"cap-corr-id\":\"1319249848986079232\",\"cap-corr-seq\":\"0\"},\"Value\":{\"DateTime\":\"2020-10-22T20:10:49.1328929+08:00\",\"AppId\":\"TEST-APP\",\"Method\":\"Create\",\"Object\":\"AggregateRoute\"}}', 0, '2020-10-22 20:10:49', '2020-10-23 20:10:49', 'Succeeded');
INSERT INTO `cap.published` VALUES (1319250220064542720, 'v1', 'LINGYUN.ApiGateway.EventBus.ApigatewayConfigChangeEventData', '{\"Headers\":{\"cap-callback-name\":null,\"cap-msg-id\":\"1319250220064542720\",\"cap-msg-name\":\"LINGYUN.ApiGateway.EventBus.ApigatewayConfigChangeEventData\",\"cap-msg-type\":\"Object\",\"cap-senttime\":\"2020/10/22 20:12:17 +08:00\",\"cap-corr-id\":\"1319250220064542720\",\"cap-corr-seq\":\"0\"},\"Value\":{\"DateTime\":\"2020-10-22T20:12:17.6028009+08:00\",\"AppId\":\"TEST-APP\",\"Method\":\"Update\",\"Object\":\"AggregateRoute\"}}', 0, '2020-10-22 20:12:18', '2020-10-23 20:12:18', 'Succeeded');
INSERT INTO `cap.published` VALUES (1319253036082499584, 'v1', 'LINGYUN.ApiGateway.EventBus.ApigatewayConfigChangeEventData', '{\"Headers\":{\"cap-callback-name\":null,\"cap-msg-id\":\"1319253036082499584\",\"cap-msg-name\":\"LINGYUN.ApiGateway.EventBus.ApigatewayConfigChangeEventData\",\"cap-msg-type\":\"Object\",\"cap-senttime\":\"2020/10/22 20:23:28 +08:00\",\"cap-corr-id\":\"1319253036082499584\",\"cap-corr-seq\":\"0\"},\"Value\":{\"DateTime\":\"2020-10-22T20:23:28.995489+08:00\",\"AppId\":\"TEST-APP\",\"Method\":\"AddRouteConfig\",\"Object\":\"AggregateRoute\"}}', 0, '2020-10-22 20:23:29', '2020-10-23 20:23:29', 'Succeeded');
INSERT INTO `cap.published` VALUES (1319269094700978176, 'v1', 'LINGYUN.ApiGateway.EventBus.ApigatewayConfigChangeEventData', '{\"Headers\":{\"cap-callback-name\":null,\"cap-msg-id\":\"1319269094700978176\",\"cap-msg-name\":\"LINGYUN.ApiGateway.EventBus.ApigatewayConfigChangeEventData\",\"cap-msg-type\":\"Object\",\"cap-senttime\":\"2020/10/22 21:27:17 +08:00\",\"cap-corr-id\":\"1319269094700978176\",\"cap-corr-seq\":\"0\"},\"Value\":{\"DateTime\":\"2020-10-22T21:27:17.6683764+08:00\",\"AppId\":\"TEST-APP\",\"Method\":\"Delete\",\"Object\":\"AggregateRoute\"}}', 0, '2020-10-22 21:27:18', '2020-10-23 21:27:18', 'Succeeded');
INSERT INTO `cap.published` VALUES (1319269302629404672, 'v1', 'LINGYUN.ApiGateway.EventBus.ApigatewayConfigChangeEventData', '{\"Headers\":{\"cap-callback-name\":null,\"cap-msg-id\":\"1319269302629404672\",\"cap-msg-name\":\"LINGYUN.ApiGateway.EventBus.ApigatewayConfigChangeEventData\",\"cap-msg-type\":\"Object\",\"cap-senttime\":\"2020/10/22 21:28:07 +08:00\",\"cap-corr-id\":\"1319269302629404672\",\"cap-corr-seq\":\"0\"},\"Value\":{\"DateTime\":\"2020-10-22T21:28:07.2407943+08:00\",\"AppId\":\"TEST-APP\",\"Method\":\"Delete\",\"Object\":\"AggregateRoute\"}}', 0, '2020-10-22 21:28:07', '2020-10-23 21:28:07', 'Succeeded');
INSERT INTO `cap.published` VALUES (1319269513921662976, 'v1', 'LINGYUN.ApiGateway.EventBus.ApigatewayConfigChangeEventData', '{\"Headers\":{\"cap-callback-name\":null,\"cap-msg-id\":\"1319269513921662976\",\"cap-msg-name\":\"LINGYUN.ApiGateway.EventBus.ApigatewayConfigChangeEventData\",\"cap-msg-type\":\"Object\",\"cap-senttime\":\"2020/10/22 21:28:57 +08:00\",\"cap-corr-id\":\"1319269513921662976\",\"cap-corr-seq\":\"0\"},\"Value\":{\"DateTime\":\"2020-10-22T21:28:57.6185875+08:00\",\"AppId\":\"TEST-APP\",\"Method\":\"Delete\",\"Object\":\"AggregateRoute\"}}', 0, '2020-10-22 21:28:58', '2020-10-23 21:28:58', 'Succeeded');
INSERT INTO `cap.published` VALUES (1319554100082085888, 'v1', 'LINGYUN.ApiGateway.EventBus.ApigatewayConfigChangeEventData', '{\"Headers\":{\"cap-callback-name\":null,\"cap-msg-id\":\"1319554100082085888\",\"cap-msg-name\":\"LINGYUN.ApiGateway.EventBus.ApigatewayConfigChangeEventData\",\"cap-msg-type\":\"Object\",\"cap-senttime\":\"2020/10/23 16:19:48 +08:00\",\"cap-corr-id\":\"1319554100082085888\",\"cap-corr-seq\":\"0\"},\"Value\":{\"DateTime\":\"2020-10-23T16:19:48.2464771+08:00\",\"AppId\":\"TEST-APP\",\"Method\":\"Modify\",\"Object\":\"ReRoute\"}}', 0, '2020-10-23 16:19:48', '2020-10-24 16:19:48', 'Succeeded');
INSERT INTO `cap.published` VALUES (1319554182298832896, 'v1', 'LINGYUN.ApiGateway.EventBus.ApigatewayConfigChangeEventData', '{\"Headers\":{\"cap-callback-name\":null,\"cap-msg-id\":\"1319554182298832896\",\"cap-msg-name\":\"LINGYUN.ApiGateway.EventBus.ApigatewayConfigChangeEventData\",\"cap-msg-type\":\"Object\",\"cap-senttime\":\"2020/10/23 16:20:07 +08:00\",\"cap-corr-id\":\"1319554182298832896\",\"cap-corr-seq\":\"0\"},\"Value\":{\"DateTime\":\"2020-10-23T16:20:07.8366727+08:00\",\"AppId\":\"TEST-APP\",\"Method\":\"Modify\",\"Object\":\"ReRoute\"}}', 0, '2020-10-23 16:20:08', '2020-10-24 16:20:08', 'Succeeded');
INSERT INTO `cap.published` VALUES (1319554431205609472, 'v1', 'LINGYUN.ApiGateway.EventBus.ApigatewayConfigChangeEventData', '{\"Headers\":{\"cap-callback-name\":null,\"cap-msg-id\":\"1319554431205609472\",\"cap-msg-name\":\"LINGYUN.ApiGateway.EventBus.ApigatewayConfigChangeEventData\",\"cap-msg-type\":\"Object\",\"cap-senttime\":\"2020/10/23 16:21:07 +08:00\",\"cap-corr-id\":\"1319554431205609472\",\"cap-corr-seq\":\"0\"},\"Value\":{\"DateTime\":\"2020-10-23T16:21:07.192283+08:00\",\"AppId\":\"TEST-APP\",\"Method\":\"Create\",\"Object\":\"ReRoute\"}}', 0, '2020-10-23 16:21:07', '2020-10-24 16:21:07', 'Succeeded');
INSERT INTO `cap.published` VALUES (1319554550520975360, 'v1', 'LINGYUN.ApiGateway.EventBus.ApigatewayConfigChangeEventData', '{\"Headers\":{\"cap-callback-name\":null,\"cap-msg-id\":\"1319554550520975360\",\"cap-msg-name\":\"LINGYUN.ApiGateway.EventBus.ApigatewayConfigChangeEventData\",\"cap-msg-type\":\"Object\",\"cap-senttime\":\"2020/10/23 16:21:35 +08:00\",\"cap-corr-id\":\"1319554550520975360\",\"cap-corr-seq\":\"0\"},\"Value\":{\"DateTime\":\"2020-10-23T16:21:35.6396895+08:00\",\"AppId\":\"TEST-APP\",\"Method\":\"Create\",\"Object\":\"ReRoute\"}}', 0, '2020-10-23 16:21:36', '2020-10-24 16:21:36', 'Succeeded');
INSERT INTO `cap.published` VALUES (1319554948505899008, 'v1', 'LINGYUN.ApiGateway.EventBus.ApigatewayConfigChangeEventData', '{\"Headers\":{\"cap-callback-name\":null,\"cap-msg-id\":\"1319554948505899008\",\"cap-msg-name\":\"LINGYUN.ApiGateway.EventBus.ApigatewayConfigChangeEventData\",\"cap-msg-type\":\"Object\",\"cap-senttime\":\"2020/10/23 16:23:10 +08:00\",\"cap-corr-id\":\"1319554948505899008\",\"cap-corr-seq\":\"0\"},\"Value\":{\"DateTime\":\"2020-10-23T16:23:10.5258597+08:00\",\"AppId\":\"TEST-APP\",\"Method\":\"Create\",\"Object\":\"ReRoute\"}}', 0, '2020-10-23 16:23:11', '2020-10-24 16:23:11', 'Succeeded');
INSERT INTO `cap.published` VALUES (1319555067250839552, 'v1', 'LINGYUN.ApiGateway.EventBus.ApigatewayConfigChangeEventData', '{\"Headers\":{\"cap-callback-name\":null,\"cap-msg-id\":\"1319555067250839552\",\"cap-msg-name\":\"LINGYUN.ApiGateway.EventBus.ApigatewayConfigChangeEventData\",\"cap-msg-type\":\"Object\",\"cap-senttime\":\"2020/10/23 16:23:38 +08:00\",\"cap-corr-id\":\"1319555067250839552\",\"cap-corr-seq\":\"0\"},\"Value\":{\"DateTime\":\"2020-10-23T16:23:38.8355819+08:00\",\"AppId\":\"TEST-APP\",\"Method\":\"Create\",\"Object\":\"ReRoute\"}}', 0, '2020-10-23 16:23:39', '2020-10-24 16:23:39', 'Succeeded');
INSERT INTO `cap.published` VALUES (1319555230837084160, 'v1', 'LINGYUN.ApiGateway.EventBus.ApigatewayConfigChangeEventData', '{\"Headers\":{\"cap-callback-name\":null,\"cap-msg-id\":\"1319555230837084160\",\"cap-msg-name\":\"LINGYUN.ApiGateway.EventBus.ApigatewayConfigChangeEventData\",\"cap-msg-type\":\"Object\",\"cap-senttime\":\"2020/10/23 16:24:17 +08:00\",\"cap-corr-id\":\"1319555230837084160\",\"cap-corr-seq\":\"0\"},\"Value\":{\"DateTime\":\"2020-10-23T16:24:17.8394311+08:00\",\"AppId\":\"TEST-APP\",\"Method\":\"Create\",\"Object\":\"ReRoute\"}}', 0, '2020-10-23 16:24:18', '2020-10-24 16:24:18', 'Succeeded');
INSERT INTO `cap.published` VALUES (1319555333865967616, 'v1', 'LINGYUN.ApiGateway.EventBus.ApigatewayConfigChangeEventData', '{\"Headers\":{\"cap-callback-name\":null,\"cap-msg-id\":\"1319555333865967616\",\"cap-msg-name\":\"LINGYUN.ApiGateway.EventBus.ApigatewayConfigChangeEventData\",\"cap-msg-type\":\"Object\",\"cap-senttime\":\"2020/10/23 16:24:42 +08:00\",\"cap-corr-id\":\"1319555333865967616\",\"cap-corr-seq\":\"0\"},\"Value\":{\"DateTime\":\"2020-10-23T16:24:42.403288+08:00\",\"AppId\":\"TEST-APP\",\"Method\":\"Create\",\"Object\":\"ReRoute\"}}', 0, '2020-10-23 16:24:42', '2020-10-24 16:24:42', 'Succeeded');
INSERT INTO `cap.published` VALUES (1319567388383744000, 'v1', 'LINGYUN.ApiGateway.EventBus.ApigatewayConfigChangeEventData', '{\"Headers\":{\"cap-callback-name\":null,\"cap-msg-id\":\"1319567388383744000\",\"cap-msg-name\":\"LINGYUN.ApiGateway.EventBus.ApigatewayConfigChangeEventData\",\"cap-msg-type\":\"Object\",\"cap-senttime\":\"2020/10/23 17:12:36 +08:00\",\"cap-corr-id\":\"1319567388383744000\",\"cap-corr-seq\":\"0\"},\"Value\":{\"DateTime\":\"2020-10-23T17:12:36.4191302+08:00\",\"AppId\":\"TEST-APP\",\"Method\":\"Modify\",\"Object\":\"ReRoute\"}}', 0, '2020-10-23 17:12:36', '2020-10-24 17:12:36', 'Succeeded');
INSERT INTO `cap.published` VALUES (1319567469363171328, 'v1', 'LINGYUN.ApiGateway.EventBus.ApigatewayConfigChangeEventData', '{\"Headers\":{\"cap-callback-name\":null,\"cap-msg-id\":\"1319567469363171328\",\"cap-msg-name\":\"LINGYUN.ApiGateway.EventBus.ApigatewayConfigChangeEventData\",\"cap-msg-type\":\"Object\",\"cap-senttime\":\"2020/10/23 17:12:55 +08:00\",\"cap-corr-id\":\"1319567469363171328\",\"cap-corr-seq\":\"0\"},\"Value\":{\"DateTime\":\"2020-10-23T17:12:55.7317902+08:00\",\"AppId\":\"TEST-APP\",\"Method\":\"Modify\",\"Object\":\"ReRoute\"}}', 0, '2020-10-23 17:12:56', '2020-10-24 17:12:56', 'Succeeded');
-- ---------------------------- -- ----------------------------
-- Table structure for cap.received -- Table structure for cap.received

15
aspnet-core/modules/common/LINGYUN.Abp.AspNetCore.SignalR.Protocol.Json/LINGYUN.Abp.AspNetCore.SignalR.Protocol.Json.csproj

@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\common.props" />
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<RootNamespace />
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.SignalR.Protocols.NewtonsoftJson" Version="3.1.6" />
<PackageReference Include="Volo.Abp.AspNetCore.SignalR" Version="3.2.0" />
</ItemGroup>
</Project>

22
aspnet-core/modules/common/LINGYUN.Abp.AspNetCore.SignalR.Protocol.Json/LINGYUN/Abp/AspNetCore/SignalR/Protocol/Json/AbpAspNetCoreSignalRProtocolJsonModule.cs

@ -0,0 +1,22 @@
using Microsoft.AspNetCore.SignalR;
using Microsoft.AspNetCore.SignalR.Protocol;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Volo.Abp.AspNetCore.SignalR;
using Volo.Abp.Modularity;
namespace LINGYUN.Abp.AspNetCore.SignalR.Protocol.Json
{
[DependsOn(
typeof(AbpAspNetCoreSignalRModule))]
public class AbpAspNetCoreSignalRProtocolJsonModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
var newtonsoftJsonOptions = new NewtonsoftJsonHubProtocolOptions();
context.Services.ExecutePreConfiguredActions(newtonsoftJsonOptions);
context.Services.TryAddEnumerable(ServiceDescriptor.Singleton<IHubProtocol, NewtonsoftJsonHubProtocol>());
}
}
}

15
aspnet-core/modules/common/LINGYUN.Abp.ExceptionHandling.Notifications/LINGYUN.Abp.ExceptionHandling.Notifications.csproj

@ -7,6 +7,21 @@
<RootNamespace /> <RootNamespace />
</PropertyGroup> </PropertyGroup>
<ItemGroup>
<None Remove="LINGYUN\Abp\ExceptionHandling\Notifications\Localization\Resources\en.json" />
<None Remove="LINGYUN\Abp\ExceptionHandling\Notifications\Localization\Resources\zh-Hans.json" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="LINGYUN\Abp\ExceptionHandling\Notifications\Localization\Resources\en.json" />
<EmbeddedResource Include="LINGYUN\Abp\ExceptionHandling\Notifications\Localization\Resources\zh-Hans.json" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Volo.Abp.Localization" Version="3.2.0" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\LINGYUN.Abp.ExceptionHandling\LINGYUN.Abp.ExceptionHandling.csproj" /> <ProjectReference Include="..\LINGYUN.Abp.ExceptionHandling\LINGYUN.Abp.ExceptionHandling.csproj" />
<ProjectReference Include="..\LINGYUN.Abp.Notifications\LINGYUN.Abp.Notifications.csproj" /> <ProjectReference Include="..\LINGYUN.Abp.Notifications\LINGYUN.Abp.Notifications.csproj" />

22
aspnet-core/modules/common/LINGYUN.Abp.ExceptionHandling.Notifications/LINGYUN/Abp/ExceptionHandling/Notifications/AbpExceptionHandlingNotificationDefinitionProvider.cs

@ -1,4 +1,6 @@
using LINGYUN.Abp.Notifications; using LINGYUN.Abp.ExceptionHandling.Localization;
using LINGYUN.Abp.Notifications;
using Volo.Abp.Localization;
namespace LINGYUN.Abp.ExceptionHandling.Notifications namespace LINGYUN.Abp.ExceptionHandling.Notifications
{ {
@ -6,7 +8,23 @@ namespace LINGYUN.Abp.ExceptionHandling.Notifications
{ {
public override void Define(INotificationDefinitionContext context) public override void Define(INotificationDefinitionContext context)
{ {
context.Add(new NotificationDefinition(AbpExceptionHandlingNotificationNames.NotificationName)); var exceptionGroup = context.AddGroup(
AbpExceptionHandlingNotificationNames.GroupName,
L("Notifications:Exception"),
false);
exceptionGroup.AddNotification(
name: AbpExceptionHandlingNotificationNames.NotificationName,
displayName: L("Notifications:ExceptionNotifier"),
description: L("Notifications:ExceptionNotifier"),
notificationType: NotificationType.System,
lifetime: NotificationLifetime.Persistent,
allowSubscriptionToClients: false);
}
protected LocalizableString L(string name)
{
return LocalizableString.Create<ExceptionHandlingResource>(name);
} }
} }
} }

3
aspnet-core/modules/common/LINGYUN.Abp.ExceptionHandling.Notifications/LINGYUN/Abp/ExceptionHandling/Notifications/AbpExceptionHandlingNotificationNames.cs

@ -2,6 +2,7 @@
{ {
public class AbpExceptionHandlingNotificationNames public class AbpExceptionHandlingNotificationNames
{ {
public const string NotificationName = "Abp.ExceptionHandling.Notifier"; public const string GroupName = "LINGYUN.Abp.ExceptionHandling";
public const string NotificationName = GroupName + ".Notifier";
} }
} }

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

@ -1,5 +1,8 @@
using LINGYUN.Abp.Notifications; using LINGYUN.Abp.ExceptionHandling.Localization;
using LINGYUN.Abp.Notifications;
using Volo.Abp.Localization;
using Volo.Abp.Modularity; using Volo.Abp.Modularity;
using Volo.Abp.VirtualFileSystem;
namespace LINGYUN.Abp.ExceptionHandling.Notifications namespace LINGYUN.Abp.ExceptionHandling.Notifications
{ {
@ -8,5 +11,19 @@ namespace LINGYUN.Abp.ExceptionHandling.Notifications
typeof(AbpNotificationModule))] typeof(AbpNotificationModule))]
public class AbpNotificationsExceptionHandlingModule : AbpModule public class AbpNotificationsExceptionHandlingModule : AbpModule
{ {
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<AbpVirtualFileSystemOptions>(options =>
{
options.FileSets.AddEmbedded<AbpNotificationsExceptionHandlingModule>();
});
Configure<AbpLocalizationOptions>(options =>
{
options.Resources
.Get<ExceptionHandlingResource>()
.AddVirtualJson("/LINGYUN/Abp/ExceptionHandling/Notifications/Localization/Resources");
});
}
} }
} }

29
aspnet-core/modules/common/LINGYUN.Abp.ExceptionHandling.Notifications/LINGYUN/Abp/ExceptionHandling/Notifications/AbpNotificationsExceptionSubscriber.cs

@ -21,26 +21,23 @@ namespace LINGYUN.Abp.ExceptionHandling.Notifications
protected override async Task SendErrorNotifierAsync(ExceptionSendNotifierContext context) protected override async Task SendErrorNotifierAsync(ExceptionSendNotifierContext context)
{ {
var notificationDispatcher = context.ServiceProvider.GetRequiredService<INotificationDispatcher>(); var notificationSender = context.ServiceProvider.GetRequiredService<INotificationSender>();
var notificationName = NotificationNameNormalizer
.NormalizerName(AbpExceptionHandlingNotificationNames.NotificationName); NotificationData notificationData = new NotificationData();
NotificationData notificationData;
if (CurrentTenant.IsAvailable)
{
notificationData = NotificationData.CreateTenantNotificationData(CurrentTenant.Id.Value);
}
else
{
notificationData = NotificationData.CreateNotificationData();
}
// 写入通知数据 // 写入通知数据
//TODO:集成TextTemplate完成格式化的推送 //TODO:集成TextTemplate完成格式化的推送
notificationData.WriteStandardData( notificationData.WriteStandardData(
context.Exception.GetType().FullName, context.Exception.Message, context.Exception.GetType().FullName,
DateTime.Now, "System"); context.Exception.Message,
DateTime.Now,
"System");
await notificationDispatcher.DispatchAsync(notificationName, notificationData, await notificationSender.SendNofiterAsync(
CurrentTenant.Id, NotificationSeverity.Error); AbpExceptionHandlingNotificationNames.NotificationName,
notificationData,
null,
CurrentTenant.Id,
NotificationSeverity.Error);
} }
} }
} }

7
aspnet-core/modules/common/LINGYUN.Abp.ExceptionHandling.Notifications/LINGYUN/Abp/ExceptionHandling/Notifications/Localization/Resources/en.json

@ -0,0 +1,7 @@
{
"culture": "en",
"texts": {
"Notifications:Exception": "Exception",
"Notifications:ExceptionNotifier": "Exception Notifier"
}
}

7
aspnet-core/modules/common/LINGYUN.Abp.ExceptionHandling.Notifications/LINGYUN/Abp/ExceptionHandling/Notifications/Localization/Resources/zh-Hans.json

@ -0,0 +1,7 @@
{
"culture": "zh-Hans",
"texts": {
"Notifications:Exception": "异常通知",
"Notifications:ExceptionNotifier": "异常推送"
}
}

2
aspnet-core/modules/common/LINGYUN.Abp.ExceptionHandling/LINGYUN.Abp.ExceptionHandling.csproj

@ -8,7 +8,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Volo.Abp.Core" Version="3.2.0" /> <PackageReference Include="Volo.Abp.Localization" Version="3.2.0" />
</ItemGroup> </ItemGroup>
</Project> </Project>

12
aspnet-core/modules/common/LINGYUN.Abp.ExceptionHandling/LINGYUN/Abp/ExceptionHandling/AbpExceptionHandlingModule.cs

@ -1,8 +1,18 @@
using Volo.Abp.Modularity; using LINGYUN.Abp.ExceptionHandling.Localization;
using Volo.Abp.Localization;
using Volo.Abp.Modularity;
namespace LINGYUN.Abp.ExceptionHandling namespace LINGYUN.Abp.ExceptionHandling
{ {
[DependsOn(typeof(AbpLocalizationModule))]
public class AbpExceptionHandlingModule : AbpModule public class AbpExceptionHandlingModule : AbpModule
{ {
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<AbpLocalizationOptions>(options =>
{
options.Resources.Add<ExceptionHandlingResource>("en");
});
}
} }
} }

9
aspnet-core/modules/common/LINGYUN.Abp.ExceptionHandling/LINGYUN/Abp/ExceptionHandling/Localization/ExceptionHandlingResource.cs

@ -0,0 +1,9 @@
using Volo.Abp.Localization;
namespace LINGYUN.Abp.ExceptionHandling.Localization
{
[LocalizationResourceName("AbpExceptionHandling")]
public class ExceptionHandlingResource
{
}
}

9
aspnet-core/modules/common/LINGYUN.Abp.IM.SignalR/LINGYUN/Abp/IM/SignalR/AbpIMSignalRModule.cs

@ -1,18 +1,23 @@
using LINGYUN.Abp.AspNetCore.SignalR.JwtToken; using LINGYUN.Abp.AspNetCore.SignalR.JwtToken;
using LINGYUN.Abp.IM.SignalR.Messages;
using LINGYUN.Abp.RealTime.SignalR; using LINGYUN.Abp.RealTime.SignalR;
using Volo.Abp.AspNetCore.SignalR;
using Volo.Abp.Modularity; using Volo.Abp.Modularity;
namespace LINGYUN.Abp.IM.SignalR namespace LINGYUN.Abp.IM.SignalR
{ {
[DependsOn( [DependsOn(
typeof(AbpIMModule),
typeof(AbpRealTimeSignalRModule), typeof(AbpRealTimeSignalRModule),
typeof(AbpAspNetCoreSignalRModule),
typeof(AbpAspNetCoreSignalRJwtTokenModule))] typeof(AbpAspNetCoreSignalRJwtTokenModule))]
public class AbpIMSignalRModule : AbpModule public class AbpIMSignalRModule : AbpModule
{ {
public override void ConfigureServices(ServiceConfigurationContext context) public override void ConfigureServices(ServiceConfigurationContext context)
{ {
Configure<AbpIMOptions>(options =>
{
options.Providers.Add<SignalRMessageSenderProvider>();
});
Configure<AbpAspNetCoreSignalRJwtTokenMapPathOptions>(options => Configure<AbpAspNetCoreSignalRJwtTokenMapPathOptions>(options =>
{ {
options.MapPath("messages"); options.MapPath("messages");

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

@ -10,7 +10,6 @@ using System;
using System.Collections.Immutable; using System.Collections.Immutable;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.Application.Dtos; using Volo.Abp.Application.Dtos;
using Volo.Abp.Users; using Volo.Abp.Users;
@ -35,6 +34,7 @@ namespace LINGYUN.Abp.IM.SignalR.Hubs
protected override async Task OnClientConnectedAsync(IOnlineClient client) protected override async Task OnClientConnectedAsync(IOnlineClient client)
{ {
await base.OnClientConnectedAsync(client);
// 加入通讯组 // 加入通讯组
var userGroups = await UserGroupStore.GetUserGroupsAsync(client.TenantId, client.UserId.Value); var userGroups = await UserGroupStore.GetUserGroupsAsync(client.TenantId, client.UserId.Value);
foreach (var group in userGroups) foreach (var group in userGroups)
@ -61,33 +61,35 @@ namespace LINGYUN.Abp.IM.SignalR.Hubs
} }
} }
protected override async Task OnClientDisconnectedAsync(IOnlineClient client) //protected override async Task OnClientDisconnectedAsync(IOnlineClient client)
{ //{
// 从通讯组断开会话 // // 从通讯组断开会话
var userGroups = await UserGroupStore.GetUserGroupsAsync(client.TenantId, client.UserId.Value); // var userGroups = await UserGroupStore.GetUserGroupsAsync(client.TenantId, client.UserId.Value, Context.ConnectionAborted);
foreach (var group in userGroups) // foreach (var group in userGroups)
{ // {
await Groups.RemoveFromGroupAsync(client.ConnectionId, group.Name); // await Groups.RemoveFromGroupAsync(client.ConnectionId, group.Name, Context.ConnectionAborted);
var groupClient = Clients.Group(group.Name); // var groupClient = Clients.Group(group.Name);
if (groupClient != null) // if (groupClient != null)
{ // {
// 发送用户下线指令 // // 发送用户下线指令
await groupClient.SendAsync("onUserOfflined", client.TenantId, client.UserId.Value); // await groupClient.SendAsync("onUserOfflined", client.TenantId, client.UserId.Value, Context.ConnectionAborted);
} // }
} // }
// 发送好友下线通知 // // 发送好友下线通知
var userFriends = await FriendStore.GetListAsync(client.TenantId, client.UserId.Value); // var userFriends = await FriendStore.GetListAsync(client.TenantId, client.UserId.Value, cancellationToken: Context.ConnectionAborted);
if (userFriends.Count > 0) // if (userFriends.Count > 0)
{ // {
var friendClientIds = userFriends.Select(friend => friend.FriendId.ToString()).ToImmutableArray(); // var friendClientIds = userFriends.Select(friend => friend.FriendId.ToString()).ToImmutableArray();
var userClients = Clients.Users(friendClientIds); // var userClients = Clients.Users(friendClientIds);
if (userClients != null) // if (userClients != null)
{ // {
await userClients.SendAsync("onUserOfflined", client.TenantId, client.UserId.Value); // await userClients.SendAsync("onUserOfflined", client.TenantId, client.UserId.Value, Context.ConnectionAborted);
} // }
} // }
}
// await base.OnClientDisconnectedAsync(client);
//}
[HubMethodName("LastContactFriends")] [HubMethodName("LastContactFriends")]
public virtual async Task<PagedResultDto<UserFriend>> GetLastContactFriendsAsync( public virtual async Task<PagedResultDto<UserFriend>> GetLastContactFriendsAsync(
@ -99,7 +101,7 @@ namespace LINGYUN.Abp.IM.SignalR.Hubs
var myFrientCount = await FriendStore.GetCountAsync(tenantId, userId); var myFrientCount = await FriendStore.GetCountAsync(tenantId, userId);
var lastContractFriends = await FriendStore var lastContractFriends = await FriendStore
.GetLastContactListAsync(tenantId, userId, skipCount, maxResultCount); .GetLastContactListAsync(tenantId, userId, skipCount, maxResultCount, cancellationToken: Context.ConnectionAborted);
return new PagedResultDto<UserFriend>(myFrientCount, lastContractFriends); return new PagedResultDto<UserFriend>(myFrientCount, lastContractFriends);
} }
@ -123,7 +125,7 @@ namespace LINGYUN.Abp.IM.SignalR.Hubs
{ {
var messages = await MessageStore var messages = await MessageStore
.GetLastChatMessagesAsync( .GetLastChatMessagesAsync(
CurrentTenant.Id, userId, sorting, reverse, maxResultCount); CurrentTenant.Id, userId, sorting, reverse, maxResultCount, cancellationToken: Context.ConnectionAborted);
return new ListResultDto<LastChatMessage>(messages); return new ListResultDto<LastChatMessage>(messages);
} }
@ -144,7 +146,7 @@ namespace LINGYUN.Abp.IM.SignalR.Hubs
bool reverse = false) bool reverse = false)
{ {
var userFriends = await FriendStore var userFriends = await FriendStore
.GetListAsync(CurrentTenant.Id, userId, sorting, reverse); .GetListAsync(CurrentTenant.Id, userId, sorting, reverse, cancellationToken: Context.ConnectionAborted);
return new ListResultDto<UserFriend>(userFriends); return new ListResultDto<UserFriend>(userFriends);
} }
@ -156,7 +158,7 @@ namespace LINGYUN.Abp.IM.SignalR.Hubs
Guid friendId, Guid friendId,
string remarkName = "") string remarkName = "")
{ {
await FriendStore.AddMemberAsync(tenantId, userId, friendId, remarkName); await FriendStore.AddRequestAsync(tenantId, userId, friendId, remarkName);
} }
[HubMethodName("RemoveFriend")] [HubMethodName("RemoveFriend")]
@ -166,7 +168,7 @@ namespace LINGYUN.Abp.IM.SignalR.Hubs
Guid friendId, Guid friendId,
string remarkName = "") string remarkName = "")
{ {
await FriendStore.RemoveMemberAsync(tenantId, userId, friendId); await FriendStore.RemoveMemberAsync(tenantId, userId, friendId, cancellationToken: Context.ConnectionAborted);
} }
/// <summary> /// <summary>
@ -178,7 +180,7 @@ namespace LINGYUN.Abp.IM.SignalR.Hubs
public virtual async Task SendMessageAsync(ChatMessage chatMessage) public virtual async Task SendMessageAsync(ChatMessage chatMessage)
{ {
// 持久化 // 持久化
await MessageStore.StoreMessageAsync(chatMessage); await MessageStore.StoreMessageAsync(chatMessage, cancellationToken: Context.ConnectionAborted);
if (!chatMessage.GroupId.IsNullOrWhiteSpace()) if (!chatMessage.GroupId.IsNullOrWhiteSpace())
{ {
@ -199,7 +201,7 @@ namespace LINGYUN.Abp.IM.SignalR.Hubs
return; return;
} }
await signalRClient.SendAsync("getChatMessage", chatMessage); await signalRClient.SendAsync("getChatMessage", chatMessage, cancellationToken: Context.ConnectionAborted);
} }
protected virtual async Task SendMessageToUserAsync(ChatMessage chatMessage) protected virtual async Task SendMessageToUserAsync(ChatMessage chatMessage)
@ -217,7 +219,7 @@ namespace LINGYUN.Abp.IM.SignalR.Hubs
Logger.LogDebug("Can not get user " + onlineClientContext.UserId + " with connectionId " + onlineClient.ConnectionId + " from SignalR hub!"); Logger.LogDebug("Can not get user " + onlineClientContext.UserId + " with connectionId " + onlineClient.ConnectionId + " from SignalR hub!");
continue; continue;
} }
await signalRClient.SendAsync("getChatMessage", chatMessage); await signalRClient.SendAsync("getChatMessage", chatMessage, cancellationToken: Context.ConnectionAborted);
} }
catch (Exception ex) catch (Exception ex)
{ {

15
aspnet-core/modules/common/LINGYUN.Abp.IM.SignalR/LINGYUN/Abp/IM/SignalR/Messages/SignalRMessageSender.cs → aspnet-core/modules/common/LINGYUN.Abp.IM.SignalR/LINGYUN/Abp/IM/SignalR/Messages/SignalRMessageSenderProvider.cs

@ -2,30 +2,27 @@
using LINGYUN.Abp.IM.SignalR.Hubs; using LINGYUN.Abp.IM.SignalR.Hubs;
using LINGYUN.Abp.RealTime.Client; using LINGYUN.Abp.RealTime.Client;
using Microsoft.AspNetCore.SignalR; using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using System; using System;
using System.Collections.Immutable; using System.Collections.Immutable;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
namespace LINGYUN.Abp.IM.SignalR.Messages namespace LINGYUN.Abp.IM.SignalR.Messages
{ {
[Dependency(ServiceLifetime.Transient, ReplaceServices = true)] public class SignalRMessageSenderProvider : MessageSenderProviderBase
[ExposeServices(typeof(IMessageSender))]
public class SignalRMessageSender : MessageSenderBase
{ {
public override string Name => "SignalR";
private readonly IOnlineClientManager _onlineClientManager; private readonly IOnlineClientManager _onlineClientManager;
private readonly IHubContext<MessagesHub> _hubContext; private readonly IHubContext<MessagesHub> _hubContext;
public SignalRMessageSender( public SignalRMessageSenderProvider(
IOnlineClientManager onlineClientManager, IOnlineClientManager onlineClientManager,
IHubContext<MessagesHub> hubContext, IHubContext<MessagesHub> hubContext,
IMessageStore messageStore, IServiceProvider serviceProvider)
ILogger<SignalRMessageSender> logger) : base(serviceProvider)
: base(messageStore, logger)
{ {
_hubContext = hubContext; _hubContext = hubContext;
_onlineClientManager = onlineClientManager; _onlineClientManager = onlineClientManager;

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

@ -9,6 +9,7 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="Volo.Abp.Auditing" Version="3.2.0" /> <PackageReference Include="Volo.Abp.Auditing" Version="3.2.0" />
<PackageReference Include="Volo.Abp.EventBus" Version="3.2.0" />
</ItemGroup> </ItemGroup>
</Project> </Project>

10
aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/AbpIMModule.cs

@ -0,0 +1,10 @@
using Volo.Abp.EventBus;
using Volo.Abp.Modularity;
namespace LINGYUN.Abp.IM
{
[DependsOn(typeof(AbpEventBusModule))]
public class AbpIMModule : AbpModule
{
}
}

15
aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/AbpIMOptions.cs

@ -0,0 +1,15 @@
using LINGYUN.Abp.IM.Messages;
using Volo.Abp.Collections;
namespace LINGYUN.Abp.IM
{
public class AbpIMOptions
{
public ITypeList<IMessageSenderProvider> Providers { get; }
public AbpIMOptions()
{
Providers = new TypeList<IMessageSenderProvider>();
}
}
}

47
aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/Contract/IFriendStore.cs

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace LINGYUN.Abp.IM.Contract namespace LINGYUN.Abp.IM.Contract
@ -16,7 +17,8 @@ namespace LINGYUN.Abp.IM.Contract
Task<bool> IsFriendAsync( Task<bool> IsFriendAsync(
Guid? tenantId, Guid? tenantId,
Guid userId, Guid userId,
Guid friendId Guid friendId,
CancellationToken cancellationToken = default
); );
/// <summary> /// <summary>
/// 查询好友列表 /// 查询好友列表
@ -30,7 +32,8 @@ namespace LINGYUN.Abp.IM.Contract
Guid? tenantId, Guid? tenantId,
Guid userId, Guid userId,
string sorting = nameof(UserFriend.UserId), string sorting = nameof(UserFriend.UserId),
bool reverse = false bool reverse = false,
CancellationToken cancellationToken = default
); );
/// <summary> /// <summary>
/// 获取好友数量 /// 获取好友数量
@ -42,7 +45,8 @@ namespace LINGYUN.Abp.IM.Contract
Task<int> GetCountAsync( Task<int> GetCountAsync(
Guid? tenantId, Guid? tenantId,
Guid userId, Guid userId,
string filter = ""); string filter = "",
CancellationToken cancellationToken = default);
/// <summary> /// <summary>
/// 获取好友列表 /// 获取好友列表
/// </summary> /// </summary>
@ -61,7 +65,8 @@ namespace LINGYUN.Abp.IM.Contract
string sorting = nameof(UserFriend.UserId), string sorting = nameof(UserFriend.UserId),
bool reverse = false, bool reverse = false,
int skipCount = 0, int skipCount = 0,
int maxResultCount = 10); int maxResultCount = 10,
CancellationToken cancellationToken = default);
/// <summary> /// <summary>
/// 获取最近联系好友列表 /// 获取最近联系好友列表
/// </summary> /// </summary>
@ -74,7 +79,8 @@ namespace LINGYUN.Abp.IM.Contract
Guid? tenantId, Guid? tenantId,
Guid userId, Guid userId,
int skipCount = 0, int skipCount = 0,
int maxResultCount = 10); int maxResultCount = 10,
CancellationToken cancellationToken = default);
/// <summary> /// <summary>
/// 获取好友信息 /// 获取好友信息
/// </summary> /// </summary>
@ -85,20 +91,36 @@ namespace LINGYUN.Abp.IM.Contract
Task<UserFriend> GetMemberAsync( Task<UserFriend> GetMemberAsync(
Guid? tenantId, Guid? tenantId,
Guid userId, Guid userId,
Guid friendId); Guid friendId,
CancellationToken cancellationToken = default);
/// <summary> /// <summary>
/// 添加好友 /// 添加好友
/// </summary> /// </summary>
/// <param name="tenantId"></param> /// <param name="tenantId"></param>
/// <param name="userId"></param> /// <param name="userId"></param>
/// <param name="friendId"></param> /// <param name="friendId"></param>
/// <returns></returns>
Task AddMemberAsync(
Guid? tenantId,
Guid userId,
Guid friendId,
string remarkName = "",
CancellationToken cancellationToken = default);
/// <summary>
/// 添加好友请求
/// </summary>
/// <param name="tenantId"></param>
/// <param name="userId"></param>
/// <param name="friendId"></param>
/// <param name="remarkName"></param> /// <param name="remarkName"></param>
/// <returns></returns> /// <returns></returns>
Task<UserAddFriendResult> AddMemberAsync( Task<UserAddFriendResult> AddRequestAsync(
Guid? tenantId, Guid? tenantId,
Guid userId, Guid userId,
Guid friendId, Guid friendId,
string remarkName = ""); string remarkName = "",
string description = "",
CancellationToken cancellationToken = default);
/// <summary> /// <summary>
/// 移除好友 /// 移除好友
/// </summary> /// </summary>
@ -109,7 +131,8 @@ namespace LINGYUN.Abp.IM.Contract
Task RemoveMemberAsync( Task RemoveMemberAsync(
Guid? tenantId, Guid? tenantId,
Guid userId, Guid userId,
Guid friendId); Guid friendId,
CancellationToken cancellationToken = default);
/// <summary> /// <summary>
/// 添加黑名单 /// 添加黑名单
/// </summary> /// </summary>
@ -120,7 +143,8 @@ namespace LINGYUN.Abp.IM.Contract
Task AddShieldMemberAsync( Task AddShieldMemberAsync(
Guid? tenantId, Guid? tenantId,
Guid userId, Guid userId,
Guid friendId); Guid friendId,
CancellationToken cancellationToken = default);
/// <summary> /// <summary>
/// 移除黑名单 /// 移除黑名单
/// </summary> /// </summary>
@ -131,6 +155,7 @@ namespace LINGYUN.Abp.IM.Contract
Task RemoveShieldMemberAsync( Task RemoveShieldMemberAsync(
Guid? tenantId, Guid? tenantId,
Guid userId, Guid userId,
Guid friendId); Guid friendId,
CancellationToken cancellationToken = default);
} }
} }

44
aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/Group/IUserGroupStore.cs

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace LINGYUN.Abp.IM.Group namespace LINGYUN.Abp.IM.Group
@ -13,7 +14,11 @@ namespace LINGYUN.Abp.IM.Group
/// <param name="groupId"></param> /// <param name="groupId"></param>
/// <param name="userId"></param> /// <param name="userId"></param>
/// <returns></returns> /// <returns></returns>
Task<bool> MemberHasInGroupAsync(Guid? tenantId, long groupId, Guid userId); Task<bool> MemberHasInGroupAsync(
Guid? tenantId,
long groupId,
Guid userId,
CancellationToken cancellationToken = default);
/// <summary> /// <summary>
/// 获取群组用户身份 /// 获取群组用户身份
/// </summary> /// </summary>
@ -21,28 +26,41 @@ namespace LINGYUN.Abp.IM.Group
/// <param name="groupId"></param> /// <param name="groupId"></param>
/// <param name="userId"></param> /// <param name="userId"></param>
/// <returns></returns> /// <returns></returns>
Task<GroupUserCard> GetUserGroupCardAsync(Guid? tenantId, long groupId, Guid userId); Task<GroupUserCard> GetUserGroupCardAsync(
Guid? tenantId,
long groupId,
Guid userId,
CancellationToken cancellationToken = default);
/// <summary> /// <summary>
/// 获取用户所在通讯组列表 /// 获取用户所在通讯组列表
/// </summary> /// </summary>
/// <param name="tenantId"></param> /// <param name="tenantId"></param>
/// <param name="userId"></param> /// <param name="userId"></param>
/// <returns></returns> /// <returns></returns>
Task<IEnumerable<Group>> GetUserGroupsAsync(Guid? tenantId, Guid userId); Task<IEnumerable<Group>> GetUserGroupsAsync(
Guid? tenantId,
Guid userId,
CancellationToken cancellationToken = default);
/// <summary> /// <summary>
/// 获取群组成员列表 /// 获取群组成员列表
/// </summary> /// </summary>
/// <param name="tenantId"></param> /// <param name="tenantId"></param>
/// <param name="groupId"></param> /// <param name="groupId"></param>
/// <returns></returns> /// <returns></returns>
Task<IEnumerable<GroupUserCard>> GetMembersAsync(Guid? tenantId, long groupId); Task<IEnumerable<GroupUserCard>> GetMembersAsync(
Guid? tenantId,
long groupId,
CancellationToken cancellationToken = default);
/// <summary> /// <summary>
/// 获取群组成员数 /// 获取群组成员数
/// </summary> /// </summary>
/// <param name="tenantId"></param> /// <param name="tenantId"></param>
/// <param name="groupId"></param> /// <param name="groupId"></param>
/// <returns></returns> /// <returns></returns>
Task<int> GetMembersCountAsync(Guid? tenantId, long groupId); Task<int> GetMembersCountAsync(
Guid? tenantId,
long groupId,
CancellationToken cancellationToken = default);
/// <summary> /// <summary>
/// 获取通讯组用户 /// 获取通讯组用户
/// </summary> /// </summary>
@ -59,7 +77,8 @@ namespace LINGYUN.Abp.IM.Group
string sorting = nameof(GroupUserCard.UserId), string sorting = nameof(GroupUserCard.UserId),
bool reverse = false, bool reverse = false,
int skipCount = 0, int skipCount = 0,
int maxResultCount = 10); int maxResultCount = 10,
CancellationToken cancellationToken = default);
/// <summary> /// <summary>
/// 用户加入通讯组 /// 用户加入通讯组
/// </summary> /// </summary>
@ -67,7 +86,12 @@ namespace LINGYUN.Abp.IM.Group
/// <param name="userId"></param> /// <param name="userId"></param>
/// <param name="groupId"></param> /// <param name="groupId"></param>
/// <returns></returns> /// <returns></returns>
Task AddUserToGroupAsync(Guid? tenantId, Guid userId, long groupId, Guid acceptUserId); Task AddUserToGroupAsync(
Guid? tenantId,
Guid userId,
long groupId,
Guid acceptUserId,
CancellationToken cancellationToken = default);
/// <summary> /// <summary>
/// 用户退出通讯组 /// 用户退出通讯组
/// </summary> /// </summary>
@ -75,6 +99,10 @@ namespace LINGYUN.Abp.IM.Group
/// <param name="userId"></param> /// <param name="userId"></param>
/// <param name="groupId"></param> /// <param name="groupId"></param>
/// <returns></returns> /// <returns></returns>
Task RemoveUserFormGroupAsync(Guid? tenantId, Guid userId, long groupId); Task RemoveUserFormGroupAsync(
Guid? tenantId,
Guid userId,
long groupId,
CancellationToken cancellationToken = default);
} }
} }

2
aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/Messages/ChatMessage.cs

@ -48,7 +48,7 @@ namespace LINGYUN.Abp.IM.Messages
/// </summary> /// </summary>
public DateTime SendTime { get; set; } public DateTime SendTime { get; set; }
/// <summary> /// <summary>
/// 是否匿名发送 /// 是否匿名发送(存储在扩展字段)
/// </summary> /// </summary>
public bool IsAnonymous { get; set; } public bool IsAnonymous { get; set; }
/// <summary> /// <summary>

10
aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/Messages/IMessageSenderProvider.cs

@ -0,0 +1,10 @@
using System.Threading.Tasks;
namespace LINGYUN.Abp.IM.Messages
{
public interface IMessageSenderProvider
{
string Name { get; }
Task SendMessageAsync(ChatMessage chatMessage);
}
}

9
aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/Messages/IMessageSenderProviderManager.cs

@ -0,0 +1,9 @@
using System.Collections.Generic;
namespace LINGYUN.Abp.IM.Messages
{
public interface IMessageSenderProviderManager
{
List<IMessageSenderProvider> Providers { get; }
}
}

20
aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/Messages/IMessageStore.cs

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace LINGYUN.Abp.IM.Messages namespace LINGYUN.Abp.IM.Messages
@ -13,7 +14,9 @@ namespace LINGYUN.Abp.IM.Messages
/// <param name="formUserId"></param> /// <param name="formUserId"></param>
/// <param name="toUserId"></param> /// <param name="toUserId"></param>
/// <returns></returns> /// <returns></returns>
Task StoreMessageAsync(ChatMessage chatMessage); Task StoreMessageAsync(
ChatMessage chatMessage,
CancellationToken cancellationToken = default);
/// <summary> /// <summary>
/// 获取群组聊天记录总数 /// 获取群组聊天记录总数
/// </summary> /// </summary>
@ -26,7 +29,8 @@ namespace LINGYUN.Abp.IM.Messages
Guid? tenantId, Guid? tenantId,
long groupId, long groupId,
string filter = "", string filter = "",
MessageType? type = null); MessageType? type = null,
CancellationToken cancellationToken = default);
/// <summary> /// <summary>
/// 获取群组聊天记录 /// 获取群组聊天记录
/// </summary> /// </summary>
@ -47,7 +51,8 @@ namespace LINGYUN.Abp.IM.Messages
bool reverse = true, bool reverse = true,
MessageType? type = null, MessageType? type = null,
int skipCount = 0, int skipCount = 0,
int maxResultCount = 10); int maxResultCount = 10,
CancellationToken cancellationToken = default);
/// <summary> /// <summary>
/// 获取上一次通讯消息记录 /// 获取上一次通讯消息记录
/// </summary> /// </summary>
@ -62,7 +67,8 @@ namespace LINGYUN.Abp.IM.Messages
Guid userId, Guid userId,
string sorting = nameof(LastChatMessage.SendTime), string sorting = nameof(LastChatMessage.SendTime),
bool reverse = true, bool reverse = true,
int maxResultCount = 10 int maxResultCount = 10,
CancellationToken cancellationToken = default
); );
/// <summary> /// <summary>
/// 获取与某个用户的聊天记录总数 /// 获取与某个用户的聊天记录总数
@ -78,7 +84,8 @@ namespace LINGYUN.Abp.IM.Messages
Guid sendUserId, Guid sendUserId,
Guid receiveUserId, Guid receiveUserId,
string filter = "", string filter = "",
MessageType? type = null); MessageType? type = null,
CancellationToken cancellationToken = default);
/// <summary> /// <summary>
/// 获取与某个用户的聊天记录 /// 获取与某个用户的聊天记录
/// </summary> /// </summary>
@ -95,6 +102,7 @@ namespace LINGYUN.Abp.IM.Messages
bool reverse = true, bool reverse = true,
MessageType? type = null, MessageType? type = null,
int skipCount = 0, int skipCount = 0,
int maxResultCount = 10); int maxResultCount = 10,
CancellationToken cancellationToken = default);
} }
} }

26
aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/Messages/MessageSender.cs

@ -0,0 +1,26 @@
using System.Threading.Tasks;
using Volo.Abp.Data;
using Volo.Abp.DependencyInjection;
using Volo.Abp.EventBus.Distributed;
namespace LINGYUN.Abp.IM.Messages
{
public class MessageSender : IMessageSender, ITransientDependency
{
protected IDistributedEventBus EventBus { get; }
public MessageSender(IDistributedEventBus eventBus)
{
EventBus = eventBus;
}
public virtual async Task SendMessageAsync(ChatMessage chatMessage)
{
chatMessage.SetProperty(nameof(ChatMessage.IsAnonymous), chatMessage.IsAnonymous);
// 如果先存储的话,就紧耦合消息处理模块了
// await Store.StoreMessageAsync(chatMessage);
await EventBus.PublishAsync(chatMessage);
}
}
}

47
aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/Messages/MessageSenderBase.cs

@ -1,47 +0,0 @@
using Microsoft.Extensions.Logging;
using System;
using System.Threading.Tasks;
namespace LINGYUN.Abp.IM.Messages
{
public abstract class MessageSenderBase : IMessageSender
{
protected IMessageStore Store { get; }
protected ILogger Logger { get; }
protected MessageSenderBase(
IMessageStore store,
ILogger logger)
{
Store = store;
Logger = logger;
}
public virtual async Task SendMessageAsync(ChatMessage chatMessage)
{
// 持久化
await Store.StoreMessageAsync(chatMessage);
try
{
if (!chatMessage.GroupId.IsNullOrWhiteSpace())
{
await SendMessageToGroupAsync(chatMessage);
}
else
{
await SendMessageToUserAsync(chatMessage);
}
}
catch (Exception ex)
{
Logger.LogWarning("Could not send message, group: {0}, formUser: {1}, toUser: {2}",
chatMessage.GroupId, chatMessage.FormUserName,
chatMessage.ToUserId.HasValue ? chatMessage.ToUserId.ToString() : "None");
Logger.LogWarning("Send group message error: {0}", ex.Message);
}
}
protected abstract Task SendMessageToGroupAsync(ChatMessage chatMessage);
protected abstract Task SendMessageToUserAsync(ChatMessage chatMessage);
}
}

70
aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/Messages/MessageSenderProviderBase.cs

@ -0,0 +1,70 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using System;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
namespace LINGYUN.Abp.IM.Messages
{
public abstract class MessageSenderProviderBase : IMessageSenderProvider, ITransientDependency
{
public abstract string Name { get; }
protected IServiceProvider ServiceProvider { get; }
protected readonly object ServiceProviderLock = new object();
public ILoggerFactory LoggerFactory => LazyGetRequiredService(ref _loggerFactory);
private ILoggerFactory _loggerFactory;
protected ILogger Logger => _lazyLogger.Value;
private Lazy<ILogger> _lazyLogger => new Lazy<ILogger>(() => LoggerFactory?.CreateLogger(GetType().FullName) ?? NullLogger.Instance, true);
protected TService LazyGetRequiredService<TService>(ref TService reference)
{
if (reference == null)
{
lock (ServiceProviderLock)
{
if (reference == null)
{
reference = ServiceProvider.GetRequiredService<TService>();
}
}
}
return reference;
}
protected MessageSenderProviderBase(IServiceProvider serviceProvider)
{
ServiceProvider = serviceProvider;
}
public virtual async Task SendMessageAsync(ChatMessage chatMessage)
{
try
{
if (!chatMessage.GroupId.IsNullOrWhiteSpace())
{
await SendMessageToGroupAsync(chatMessage);
}
else
{
await SendMessageToUserAsync(chatMessage);
}
}
catch (Exception ex)
{
Logger.LogWarning("Could not send message, group: {0}, formUser: {1}, toUser: {2}",
chatMessage.GroupId, chatMessage.FormUserName,
chatMessage.ToUserId.HasValue ? chatMessage.ToUserId.ToString() : "None");
Logger.LogWarning("Send group message error: {0}", ex.Message);
}
}
protected abstract Task SendMessageToGroupAsync(ChatMessage chatMessage);
protected abstract Task SendMessageToUserAsync(ChatMessage chatMessage);
}
}

33
aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/Messages/MessageSenderProviderManager.cs

@ -0,0 +1,33 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Linq;
using Volo.Abp.DependencyInjection;
namespace LINGYUN.Abp.IM.Messages
{
public class MessageSenderProviderManager : IMessageSenderProviderManager, ISingletonDependency
{
public List<IMessageSenderProvider> Providers => _lazyProviders.Value;
protected AbpIMOptions Options { get; }
private readonly Lazy<List<IMessageSenderProvider>> _lazyProviders;
public MessageSenderProviderManager(
IServiceProvider serviceProvider,
IOptions<AbpIMOptions> options)
{
Options = options.Value;
_lazyProviders = new Lazy<List<IMessageSenderProvider>>(
() => Options
.Providers
.Select(type => serviceProvider.GetRequiredService(type) as IMessageSenderProvider)
.ToList(),
true
);
}
}
}

26
aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/Messages/NullMessageSender.cs

@ -1,26 +0,0 @@
using Microsoft.Extensions.Logging;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
namespace LINGYUN.Abp.IM.Messages
{
public class NullMessageSender : MessageSenderBase, ITransientDependency
{
public NullMessageSender(IMessageStore store, ILogger<NullMessageSender> logger)
: base(store, logger)
{
}
protected override Task SendMessageToGroupAsync(ChatMessage chatMessage)
{
Logger.LogWarning("No IMessageSender Interface implementation!");
return Task.CompletedTask;
}
protected override Task SendMessageToUserAsync(ChatMessage chatMessage)
{
Logger.LogWarning("No IMessageSender Interface implementation!");
return Task.CompletedTask;
}
}
}

41
aspnet-core/modules/common/LINGYUN.Abp.Notifications.SignalR/LINGYUN/Abp/Notifications/SignalR/Hubs/NotificationsHub.cs

@ -4,6 +4,7 @@ using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.SignalR; using Microsoft.AspNetCore.SignalR;
using System.Threading.Tasks; using System.Threading.Tasks;
using Volo.Abp.Application.Dtos; using Volo.Abp.Application.Dtos;
using Volo.Abp.Uow;
using Volo.Abp.Users; using Volo.Abp.Users;
namespace LINGYUN.Abp.Notifications.SignalR.Hubs namespace LINGYUN.Abp.Notifications.SignalR.Hubs
@ -16,27 +17,49 @@ namespace LINGYUN.Abp.Notifications.SignalR.Hubs
protected override async Task OnClientConnectedAsync(IOnlineClient client) protected override async Task OnClientConnectedAsync(IOnlineClient client)
{ {
await base.OnClientConnectedAsync(client);
if (client.TenantId.HasValue) if (client.TenantId.HasValue)
{ {
// 以租户为分组,将用户加入租户通讯组 // 以租户为分组,将用户加入租户通讯组
await Groups.AddToGroupAsync(client.ConnectionId, client.TenantId.Value.ToString()); await Groups.AddToGroupAsync(client.ConnectionId, client.TenantId.Value.ToString(), Context.ConnectionAborted);
}
else
{
await Groups.AddToGroupAsync(client.ConnectionId, "Global", Context.ConnectionAborted);
} }
} }
protected override async Task OnClientDisconnectedAsync(IOnlineClient client) protected override async Task OnClientDisconnectedAsync(IOnlineClient client)
{ {
await base.OnClientDisconnectedAsync(client);
if (client.TenantId.HasValue) if (client.TenantId.HasValue)
{ {
// 以租户为分组,将移除租户通讯组 // 以租户为分组,将移除租户通讯组
await Groups.RemoveFromGroupAsync(client.ConnectionId, client.TenantId.Value.ToString()); await Groups.RemoveFromGroupAsync(client.ConnectionId, client.TenantId.Value.ToString(), Context.ConnectionAborted);
}
else
{
await Groups.RemoveFromGroupAsync(client.ConnectionId, "Global", Context.ConnectionAborted);
} }
} }
[HubMethodName("MySubscriptions")]
public virtual async Task<ListResultDto<NotificationSubscriptionInfo>> GetMySubscriptionsAsync()
{
var subscriptions = await NotificationStore
.GetUserSubscriptionsAsync(CurrentTenant.Id, CurrentUser.GetId());
return new ListResultDto<NotificationSubscriptionInfo>(subscriptions);
}
[UnitOfWork]
[HubMethodName("GetNotification")] [HubMethodName("GetNotification")]
public virtual async Task<ListResultDto<NotificationInfo>> GetNotificationAsync( public virtual async Task<ListResultDto<NotificationInfo>> GetNotificationAsync()
NotificationReadState readState = NotificationReadState.UnRead, int maxResultCount = 10)
{ {
var userNotifications = await NotificationStore.GetUserNotificationsAsync(CurrentTenant.Id, CurrentUser.GetId(), readState, maxResultCount); var userNotifications = await NotificationStore
.GetUserNotificationsAsync(CurrentTenant.Id, CurrentUser.GetId(), NotificationReadState.UnRead, 10);
return new ListResultDto<NotificationInfo>(userNotifications); return new ListResultDto<NotificationInfo>(userNotifications);
} }
@ -44,7 +67,13 @@ namespace LINGYUN.Abp.Notifications.SignalR.Hubs
[HubMethodName("ChangeState")] [HubMethodName("ChangeState")]
public virtual async Task ChangeStateAsync(string id, NotificationReadState readState = NotificationReadState.Read) public virtual async Task ChangeStateAsync(string id, NotificationReadState readState = NotificationReadState.Read)
{ {
await NotificationStore.ChangeUserNotificationReadStateAsync(CurrentTenant.Id, CurrentUser.GetId(), long.Parse(id), readState); await NotificationStore
.ChangeUserNotificationReadStateAsync(
CurrentTenant.Id,
CurrentUser.GetId(),
long.Parse(id),
readState,
Context.ConnectionAborted);
} }
} }
} }

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

@ -6,6 +6,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Immutable; using System.Collections.Immutable;
using System.Linq; using System.Linq;
using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace LINGYUN.Abp.Notifications.SignalR namespace LINGYUN.Abp.Notifications.SignalR
@ -29,69 +30,41 @@ namespace LINGYUN.Abp.Notifications.SignalR
_onlineClientManager = onlineClientManager; _onlineClientManager = onlineClientManager;
} }
public override async Task PublishAsync(NotificationInfo notification, IEnumerable<UserIdentifier> identifiers) protected override async Task PublishAsync(NotificationInfo notification, IEnumerable<UserIdentifier> identifiers, CancellationToken cancellationToken = default)
{ {
if (notification.Data.HasTenantNotification(out Guid tenantId)) if (identifiers?.Count() == 0)
{ {
// 返回标准数据给前端 var groupName = notification.TenantId?.ToString() ?? "Global";
notification.Data = NotificationData.ToStandardData(notification.Data);
var singalRGroup = _hubContext.Clients.Group(tenantId.ToString()); var singalRGroup = _hubContext.Clients.Group(groupName);
if (singalRGroup == null) if (singalRGroup == null)
{ {
Logger.LogDebug("Can not get group " + tenantId + " from SignalR hub!"); Logger.LogDebug("Can not get group " + groupName + " from SignalR hub!");
return; return;
} }
// 租户通知群发 // 租户通知群发
Logger.LogDebug($"Found a singalr group, begin senging notifications"); Logger.LogDebug($"Found a singalr group, begin senging notifications");
await singalRGroup.SendAsync("getNotification", notification); await singalRGroup.SendAsync("getNotification", notification, cancellationToken);
} }
else else
{ {
// 返回标准数据给前端 var onlineClients = _onlineClientManager.GetAllClients(client => identifiers.Any(ids => client.UserId == ids.UserId));
notification.Data = NotificationData.ToStandardData(notification.Data); var onlineClientConnectionIds = onlineClients.Select(client => client.ConnectionId).ToImmutableArray();
foreach (var identifier in identifiers) try
{ {
Logger.LogDebug($"Find online client with user {identifier.UserId} - {identifier.UserName}"); var signalRClients = _hubContext.Clients.Clients(onlineClientConnectionIds);
var onlineClientContext = new OnlineClientContext(notification.TenantId, identifier.UserId); if (signalRClients == null)
var onlineClients = _onlineClientManager.GetAllByContext(onlineClientContext);
var onlineClientConnectionIds = onlineClients.Select(client => client.ConnectionId).ToImmutableArray();
try
{
var signalRClients = _hubContext.Clients.Clients(onlineClientConnectionIds);
if (signalRClients == null)
{
Logger.LogDebug("Can not get user " + onlineClientContext.UserId + " connection from SignalR hub!");
return;
}
Logger.LogDebug($"Found a singalr client, begin senging notifications");
await signalRClients.SendAsync("getNotification", notification);
}
catch (Exception ex)
{ {
Logger.LogWarning("Could not send notifications to user: {0}", identifier.UserId); Logger.LogDebug("Can not get users connection from SignalR hub!");
Logger.LogWarning("Send to user notifications error: {0}", ex.Message); return;
} }
Logger.LogDebug($"Found a singalr client, begin senging notifications");
//foreach (var onlineClient in onlineClients) await signalRClients.SendAsync("getNotification", notification, cancellationToken);
//{ }
// try catch (Exception ex)
// { {
// Logger.LogDebug($"Find online client {onlineClient.UserId} - {onlineClient.ConnectionId}"); Logger.LogWarning("Could not send notifications to all users");
// var signalRClient = _hubContext.Clients.Client(onlineClient.ConnectionId); Logger.LogWarning("Send to user notifications error: {0}", ex.Message);
// if (signalRClient == null)
// {
// Logger.LogDebug("Can not get user " + onlineClientContext.UserId + " with connectionId " + onlineClient.ConnectionId + " from SignalR hub!");
// continue;
// }
// Logger.LogDebug($"Found a singalr client, begin senging notifications");
// await signalRClient.SendAsync("getNotification", notification);
// }
// catch (Exception ex)
// {
// Logger.LogWarning("Could not send notifications to user: {0}", identifier.UserId);
// Logger.LogWarning("Send to user notifications error: {0}", ex.Message);
// }
//}
} }
} }
} }

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

@ -9,6 +9,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\LINGYUN.Abp.Features.LimitValidation\LINGYUN.Abp.Features.LimitValidation.csproj" />
<ProjectReference Include="..\LINGYUN.Abp.WeChat.Authorization\LINGYUN.Abp.WeChat.Authorization.csproj" /> <ProjectReference Include="..\LINGYUN.Abp.WeChat.Authorization\LINGYUN.Abp.WeChat.Authorization.csproj" />
<ProjectReference Include="..\LINGYUN.Abp.Notifications\LINGYUN.Abp.Notifications.csproj" /> <ProjectReference Include="..\LINGYUN.Abp.Notifications\LINGYUN.Abp.Notifications.csproj" />
</ItemGroup> </ItemGroup>

54
aspnet-core/modules/common/LINGYUN.Abp.Notifications.WeChat/LINGYUN/Abp/Notifications/WeChat/WeApp/Features/WeChatWeAppFeatureDefinitionProvider.cs

@ -0,0 +1,54 @@
using LINGYUN.Abp.WeChat.Features;
using LINGYUN.Abp.WeChat.Localization;
using Volo.Abp.Features;
using Volo.Abp.Localization;
using Volo.Abp.Validation.StringValues;
namespace LINGYUN.Abp.Notifications.WeChat.WeApp.Features
{
public class WeChatWeAppFeatureDefinitionProvider : FeatureDefinitionProvider
{
public override void Define(IFeatureDefinitionContext context)
{
var wechatGroup = context.GetGroupOrNull(WeChatFeatures.GroupName);
if (wechatGroup != null)
{
var weappFeature = wechatGroup
.AddFeature(
WeChatWeAppFeatures.GroupName,
true.ToString(),
L("Features:WeApp"),
L("Features:WeAppDescription"),
new ToggleStringValueType(new BooleanValueValidator()));
var weappNofitication = weappFeature
.CreateChild(
WeChatWeAppFeatures.Notifications.Default,
true.ToString(),
L("Features:Notifications"),
L("Features:Notifications"),
new ToggleStringValueType(new BooleanValueValidator()));
weappNofitication
.CreateChild(
WeChatWeAppFeatures.Notifications.PublishLimit,
WeChatWeAppFeatures.Notifications.DefaultPublishLimit.ToString(),
L("Features:PublishLimit"),
L("Features:PublishLimitDescription"),
new ToggleStringValueType(new NumericValueValidator(0, 100000)));
weappNofitication
.CreateChild(
WeChatWeAppFeatures.Notifications.PublishLimitInterval,
WeChatWeAppFeatures.Notifications.DefaultPublishLimitInterval.ToString(),
L("Features:PublishLimitInterval"),
L("Features:PublishLimitIntervalDescription"),
new ToggleStringValueType(new NumericValueValidator(1, 12)));
}
}
protected LocalizableString L(string name)
{
return LocalizableString.Create<WeChatResource>(name);
}
}
}

30
aspnet-core/modules/common/LINGYUN.Abp.Notifications.WeChat/LINGYUN/Abp/Notifications/WeChat/WeApp/Features/WeChatWeAppFeatures.cs

@ -0,0 +1,30 @@
using LINGYUN.Abp.WeChat.Features;
namespace LINGYUN.Abp.Notifications.WeChat.WeApp.Features
{
public static class WeChatWeAppFeatures
{
public const string GroupName = WeChatFeatures.GroupName + ".WeApp";
public static class Notifications
{
public const string Default = GroupName + ".Notifications";
/// <summary>
/// 发布次数上限
/// </summary>
public const string PublishLimit = Default + ".PublishLimit";
/// <summary>
/// 发布次数上限时长
/// </summary>
public const string PublishLimitInterval = Default + ".PublishLimitInterval";
/// <summary>
/// 默认发布次数上限
/// </summary>
public const int DefaultPublishLimit = 1000;
/// <summary>
/// 默认发布次数上限时长
/// </summary>
public const int DefaultPublishLimitInterval = 1;
}
}
}

5
aspnet-core/modules/common/LINGYUN.Abp.Notifications.WeChat/LINGYUN/Abp/Notifications/WeChat/WeApp/IWeChatWeAppNotificationSender.cs

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

58
aspnet-core/modules/common/LINGYUN.Abp.Notifications.WeChat/LINGYUN/Abp/Notifications/WeChat/WeApp/WeChatWeAppNotificationPublishProvider.cs

@ -1,9 +1,12 @@
using Microsoft.Extensions.Logging; using LINGYUN.Abp.Notifications.WeChat.WeApp.Features;
using LINGYUN.Abp.WeChat.Authorization;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Volo.Abp.Features;
namespace LINGYUN.Abp.Notifications.WeChat.WeApp namespace LINGYUN.Abp.Notifications.WeChat.WeApp
{ {
@ -13,8 +16,13 @@ namespace LINGYUN.Abp.Notifications.WeChat.WeApp
public class WeChatWeAppNotificationPublishProvider : NotificationPublishProvider public class WeChatWeAppNotificationPublishProvider : NotificationPublishProvider
{ {
public override string Name => "WeChat.WeApp"; public override string Name => "WeChat.WeApp";
private INotificationSubscriptionManager _notificationSubscriptionManager;
protected INotificationSubscriptionManager NotificationSubscriptionManager => LazyGetRequiredService(ref _notificationSubscriptionManager); private IFeatureChecker _featureChecker;
protected IFeatureChecker FeatureChecker => LazyGetRequiredService(ref _featureChecker);
private IWeChatOpenIdFinder _weChatOpenIdFinder;
protected IWeChatOpenIdFinder WeChatOpenIdFinder => LazyGetRequiredService(ref _weChatOpenIdFinder);
protected IWeChatWeAppNotificationSender NotificationSender { get; } protected IWeChatWeAppNotificationSender NotificationSender { get; }
protected AbpWeChatWeAppNotificationOptions Options { get; } protected AbpWeChatWeAppNotificationOptions Options { get; }
public WeChatWeAppNotificationPublishProvider( public WeChatWeAppNotificationPublishProvider(
@ -27,32 +35,39 @@ namespace LINGYUN.Abp.Notifications.WeChat.WeApp
NotificationSender = notificationSender; NotificationSender = notificationSender;
} }
public override async Task PublishAsync(NotificationInfo notification, IEnumerable<UserIdentifier> identifiers) protected override async Task PublishAsync(NotificationInfo notification, IEnumerable<UserIdentifier> identifiers, CancellationToken cancellationToken = default)
{ {
// 先检测微信小程序的功能限制
var publishEnabled = await FeatureChecker.GetAsync(WeChatWeAppFeatures.Notifications.Default, false);
if (!publishEnabled)
{
return;
}
// step1 默认微信openid绑定的就是username, // step1 默认微信openid绑定的就是username,
// 如果不是,需要自行处理openid获取逻辑 // 如果不是,需要自行处理openid获取逻辑
// step2 调用微信消息推送接口 // step2 调用微信消息推送接口
// 微信不支持推送到所有用户,需要获取订阅列表再发送 // 微信不支持推送到所有用户
// 在小程序里用户订阅消息后通过 api/subscribes/subscribe 接口订阅对应模板消息 // 在小程序里用户订阅消息后通过 api/subscribes/subscribe 接口订阅对应模板消息
if (identifiers == null)
{
var userSubscriptions = await NotificationSubscriptionManager
.GetSubscriptionsAsync(notification.TenantId, notification.Name);
identifiers = userSubscriptions
.Select(us => new UserIdentifier(us.UserId, us.UserName));
}
foreach (var identifier in identifiers) foreach (var identifier in identifiers)
{ {
await SendWeChatTemplateMessagAsync(notification, identifier); await SendWeChatTemplateMessagAsync(notification, identifier, cancellationToken);
} }
} }
protected virtual async Task SendWeChatTemplateMessagAsync(NotificationInfo notification, UserIdentifier identifier) protected virtual async Task SendWeChatTemplateMessagAsync(NotificationInfo notification, UserIdentifier identifier, CancellationToken cancellationToken = default)
{ {
var templateId = GetOrDefaultTemplateId(notification.Data); var templateId = GetOrDefaultTemplateId(notification.Data);
if (templateId.IsNullOrWhiteSpace())
{
Logger.LogWarning("Wechat weapp template id be empty, can not send notification!");
return;
}
Logger.LogDebug($"Get wechat weapp template id: {templateId}"); Logger.LogDebug($"Get wechat weapp template id: {templateId}");
var redirect = GetOrDefault(notification.Data, "RedirectPage", null); var redirect = GetOrDefault(notification.Data, "RedirectPage", null);
@ -64,13 +79,22 @@ namespace LINGYUN.Abp.Notifications.WeChat.WeApp
var weAppLang = GetOrDefault(notification.Data, "WeAppLanguage", Options.DefaultWeAppLanguage); var weAppLang = GetOrDefault(notification.Data, "WeAppLanguage", Options.DefaultWeAppLanguage);
Logger.LogDebug($"Get wechat weapp language: {weAppLang ?? null}"); Logger.LogDebug($"Get wechat weapp language: {weAppLang ?? null}");
var weChatWeAppNotificationData = new WeChatWeAppSendNotificationData(identifier.UserName, // TODO: 如果微信端发布通知,请组装好 wx-code 字段在通知数据内容里面
string weChatCode = GetOrDefault(notification.Data, "wx-code", "");
WeChatOpenId openId = weChatCode.IsNullOrWhiteSpace()
? await WeChatOpenIdFinder.FindByUserNameAsync(identifier.UserName) // 按照实际情况,需要自行实现 IUserWeChatCodeFinder 接口以获取微信Code,然后通过Code来获取OpenId
: await WeChatOpenIdFinder.FindAsync(weChatCode);
var weChatWeAppNotificationData = new WeChatWeAppSendNotificationData(openId.OpenId,
templateId, redirect, weAppState, weAppLang); templateId, redirect, weAppState, weAppLang);
// 写入模板数据 // 写入模板数据
weChatWeAppNotificationData.WriteStandardData(NotificationData.ToStandardData(Options.DefaultMsgPrefix, notification.Data)); weChatWeAppNotificationData.WriteStandardData(NotificationData.ToStandardData(Options.DefaultMsgPrefix, notification.Data));
Logger.LogDebug($"Sending wechat weapp notification: {notification.Name}"); Logger.LogDebug($"Sending wechat weapp notification: {notification.Name}");
// 发送小程序订阅消息 // 发送小程序订阅消息
await NotificationSender.SendAsync(weChatWeAppNotificationData); await NotificationSender.SendAsync(weChatWeAppNotificationData);
} }

21
aspnet-core/modules/common/LINGYUN.Abp.Notifications.WeChat/LINGYUN/Abp/Notifications/WeChat/WeApp/WeChatWeAppNotificationSender.cs

@ -1,13 +1,17 @@
using LINGYUN.Abp.WeChat.Authorization; using LINGYUN.Abp.Features.LimitValidation;
using LINGYUN.Abp.Notifications.WeChat.WeApp.Features;
using LINGYUN.Abp.WeChat.Authorization;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Logging.Abstractions;
using Newtonsoft.Json; using Newtonsoft.Json;
using System.Collections.Generic; using System.Collections.Generic;
using System.Net.Http; using System.Net.Http;
using System.Text; using System.Text;
using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Volo.Abp; using Volo.Abp;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
using Volo.Abp.Features;
using Volo.Abp.Json; using Volo.Abp.Json;
namespace LINGYUN.Abp.Notifications.WeChat.WeApp namespace LINGYUN.Abp.Notifications.WeChat.WeApp
@ -31,7 +35,14 @@ namespace LINGYUN.Abp.Notifications.WeChat.WeApp
Logger = NullLogger<WeChatWeAppNotificationSender>.Instance; Logger = NullLogger<WeChatWeAppNotificationSender>.Instance;
} }
public virtual async Task SendAsync(WeChatWeAppSendNotificationData notificationData) [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(); var weChatToken = await WeChatTokenProvider.GetTokenAsync();
var requestParamters = new Dictionary<string, string> var requestParamters = new Dictionary<string, string>
@ -41,7 +52,7 @@ namespace LINGYUN.Abp.Notifications.WeChat.WeApp
var weChatSendNotificationUrl = "https://api.weixin.qq.com"; var weChatSendNotificationUrl = "https://api.weixin.qq.com";
var weChatSendNotificationPath = "/cgi-bin/message/subscribe/send"; var weChatSendNotificationPath = "/cgi-bin/message/subscribe/send";
var requestUrl = BuildRequestUrl(weChatSendNotificationUrl, weChatSendNotificationPath, requestParamters); var requestUrl = BuildRequestUrl(weChatSendNotificationUrl, weChatSendNotificationPath, requestParamters);
var responseContent = await MakeRequestAndGetResultAsync(requestUrl, notificationData); var responseContent = await MakeRequestAndGetResultAsync(requestUrl, notificationData, cancellationToken);
var weChatSenNotificationResponse = JsonSerializer.Deserialize<WeChatSendNotificationResponse>(responseContent); var weChatSenNotificationResponse = JsonSerializer.Deserialize<WeChatSendNotificationResponse>(responseContent);
if (!weChatSenNotificationResponse.IsSuccessed) if (!weChatSenNotificationResponse.IsSuccessed)
@ -52,7 +63,7 @@ namespace LINGYUN.Abp.Notifications.WeChat.WeApp
// 失败是否抛出异常 // 失败是否抛出异常
// weChatSenNotificationResponse.ThrowIfNotSuccess(); // weChatSenNotificationResponse.ThrowIfNotSuccess();
} }
protected virtual async Task<string> MakeRequestAndGetResultAsync(string url, WeChatWeAppSendNotificationData notificationData) protected virtual async Task<string> MakeRequestAndGetResultAsync(string url, WeChatWeAppSendNotificationData notificationData, CancellationToken cancellationToken = default)
{ {
var client = HttpClientFactory.CreateClient(SendNotificationClientName); var client = HttpClientFactory.CreateClient(SendNotificationClientName);
var sendDataContent = JsonSerializer.Serialize(notificationData); var sendDataContent = JsonSerializer.Serialize(notificationData);
@ -62,7 +73,7 @@ namespace LINGYUN.Abp.Notifications.WeChat.WeApp
Content = requestContent Content = requestContent
}; };
var response = await client.SendAsync(requestMessage); var response = await client.SendAsync(requestMessage, cancellationToken);
if (!response.IsSuccessStatusCode) if (!response.IsSuccessStatusCode)
{ {
throw new AbpException($"WeChat send subscribe message http request service returns error! HttpStatusCode: {response.StatusCode}, ReasonPhrase: {response.ReasonPhrase}"); throw new AbpException($"WeChat send subscribe message http request service returns error! HttpStatusCode: {response.StatusCode}, ReasonPhrase: {response.ReasonPhrase}");

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

@ -22,11 +22,6 @@ namespace LINGYUN.Abp.Notifications
AutoAddDefinitionProviders(context.Services); AutoAddDefinitionProviders(context.Services);
} }
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.AddTransient<INotificationDispatcher, DefaultNotificationDispatcher>();
}
public override void OnApplicationInitialization(ApplicationInitializationContext context) public override void OnApplicationInitialization(ApplicationInitializationContext context)
{ {
var options = context.ServiceProvider.GetRequiredService<IOptions<AbpNotificationCleanupOptions>>().Value; var options = context.ServiceProvider.GetRequiredService<IOptions<AbpNotificationCleanupOptions>>().Value;

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

@ -1,9 +1,18 @@
namespace LINGYUN.Abp.Notifications using JetBrains.Annotations;
using Volo.Abp.Localization;
using Volo.Abp.MultiTenancy;
namespace LINGYUN.Abp.Notifications
{ {
public interface INotificationDefinitionContext public interface INotificationDefinitionContext
{ {
NotificationDefinition GetOrNull(string category); NotificationGroupDefinition AddGroup(
[NotNull] string name,
ILocalizableString displayName = null,
bool allowSubscriptionToClients = true);
NotificationGroupDefinition GetGroupOrNull(string name);
void Add(params NotificationDefinition[] definitions); void RemoveGroup(string name);
} }
} }

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

@ -6,10 +6,12 @@ namespace LINGYUN.Abp.Notifications
public interface INotificationDefinitionManager public interface INotificationDefinitionManager
{ {
[NotNull] [NotNull]
NotificationDefinition Get([NotNull] string category); NotificationDefinition Get([NotNull] string name);
IReadOnlyList<NotificationDefinition> GetAll(); IReadOnlyList<NotificationDefinition> GetAll();
NotificationDefinition GetOrNull(string category); NotificationDefinition GetOrNull(string name);
IReadOnlyList<NotificationGroupDefinition> GetGroups();
} }
} }

41
aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/INotificationDispatcher.cs

@ -6,28 +6,29 @@ namespace LINGYUN.Abp.Notifications
/// <summary> /// <summary>
/// 通知发送者接口 /// 通知发送者接口
/// </summary> /// </summary>
[Obsolete("Notification system redesigned, publisher interface deactivated, please use INotificationSender")]
public interface INotificationDispatcher public interface INotificationDispatcher
{ {
/// <summary> ///// <summary>
/// 发送通知 ///// 发送通知
/// </summary> ///// </summary>
/// <param name="notificationName">通知名称</param> ///// <param name="notificationName">通知名称</param>
/// <param name="data">数据</param> ///// <param name="data">数据</param>
/// <param name="tenantId">租户</param> ///// <param name="tenantId">租户</param>
/// <param name="notificationSeverity">级别</param> ///// <param name="notificationSeverity">级别</param>
/// <returns></returns> ///// <returns></returns>
Task DispatchAsync(NotificationName notificationName, NotificationData data, Guid? tenantId = null, //Task DispatchAsync(NotificationName notificationName, NotificationData data, Guid? tenantId = null,
NotificationSeverity notificationSeverity = NotificationSeverity.Info); // NotificationSeverity notificationSeverity = NotificationSeverity.Info);
/// <summary> ///// <summary>
/// 发送通知事件 ///// 发送通知事件
/// </summary> ///// </summary>
/// <param name="notificationName">通知名称</param> ///// <param name="notificationName">通知名称</param>
/// <param name="data">数据</param> ///// <param name="data">数据</param>
/// <param name="tenantId">租户</param> ///// <param name="tenantId">租户</param>
/// <param name="notificationSeverity">级别</param> ///// <param name="notificationSeverity">级别</param>
/// <returns></returns> ///// <returns></returns>
Task DispatchEventAsync(NotificationName notificationName, NotificationData data, Guid? tenantId = null, //Task DispatchEventAsync(NotificationName notificationName, NotificationData data, Guid? tenantId = null,
NotificationSeverity notificationSeverity = NotificationSeverity.Info); // NotificationSeverity notificationSeverity = NotificationSeverity.Info);
} }
} }

41
aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/INotificationSender.cs

@ -0,0 +1,41 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace LINGYUN.Abp.Notifications
{
/// <summary>
/// 发送通知接口
/// </summary>
public interface INotificationSender
{
/// <summary>
/// 发送通知
/// </summary>
/// <param name="name">名称</param>
/// <param name="data">数据</param>
/// <param name="userId">用户,为空标识发给所有订阅用户</param>
/// <param name="tenantId">租户</param>
/// <param name="severity">严重级别</param>
Task SendNofiterAsync(
string name,
NotificationData data,
UserIdentifier user = null,
Guid? tenantId = null,
NotificationSeverity severity = NotificationSeverity.Info);
/// <summary>
/// 发送通知
/// </summary>
/// <param name="name">名称</param>
/// <param name="data">数据</param>
/// <param name="users">用户列表,为空标识发给所有订阅用户</param>
/// <param name="tenantId">租户</param>
/// <param name="severity">严重级别</param>
Task SendNofitersAsync(
string name,
NotificationData data,
IEnumerable<UserIdentifier> users = null,
Guid? tenantId = null,
NotificationSeverity severity = NotificationSeverity.Info);
}
}

151
aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/INotificationStore.cs

@ -1,45 +1,126 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace LINGYUN.Abp.Notifications namespace LINGYUN.Abp.Notifications
{ {
public interface INotificationStore public interface INotificationStore
{ {
Task InsertUserSubscriptionAsync(Guid? tenantId, UserIdentifier identifier, string notificationName); Task InsertUserSubscriptionAsync(
Guid? tenantId,
Task InsertUserSubscriptionAsync(Guid? tenantId, IEnumerable<UserIdentifier> identifiers, string notificationName); UserIdentifier identifier,
string notificationName,
Task DeleteUserSubscriptionAsync(Guid? tenantId, Guid userId, string notificationName); CancellationToken cancellationToken = default);
Task DeleteAllUserSubscriptionAsync(Guid? tenantId, string notificationName); Task InsertUserSubscriptionAsync(
Guid? tenantId,
Task DeleteUserSubscriptionAsync(Guid? tenantId, IEnumerable<UserIdentifier> identifiers, string notificationName); IEnumerable<UserIdentifier> identifiers,
string notificationName,
Task<List<NotificationSubscriptionInfo>> GetSubscriptionsAsync(Guid? tenantId, string notificationName); CancellationToken cancellationToken = default);
Task<List<NotificationSubscriptionInfo>> GetUserSubscriptionsAsync(Guid? tenantId, Guid userId); Task DeleteUserSubscriptionAsync(
Guid? tenantId,
Task<List<NotificationSubscriptionInfo>> GetUserSubscriptionsAsync(Guid? tenantId, string userName); Guid userId,
string notificationName,
Task<bool> IsSubscribedAsync(Guid? tenantId, Guid userId, string notificationName); CancellationToken cancellationToken = default);
Task InsertNotificationAsync(NotificationInfo notification); Task DeleteAllUserSubscriptionAsync(
Guid? tenantId,
Task DeleteNotificationAsync(NotificationInfo notification); string notificationName,
CancellationToken cancellationToken = default);
Task DeleteNotificationAsync(int batchCount);
Task DeleteUserSubscriptionAsync(
Task InsertUserNotificationAsync(NotificationInfo notification, Guid userId); Guid? tenantId,
IEnumerable<UserIdentifier> identifiers,
Task InsertUserNotificationsAsync(NotificationInfo notification, IEnumerable<Guid> userIds); string notificationName,
CancellationToken cancellationToken = default);
Task DeleteUserNotificationAsync(Guid? tenantId, Guid userId, long notificationId);
Task<List<NotificationSubscriptionInfo>> GetUserSubscriptionsAsync(
Task<NotificationInfo> GetNotificationOrNullAsync(Guid? tenantId, long notificationId); Guid? tenantId,
string notificationName,
Task<List<NotificationInfo>> GetUserNotificationsAsync(Guid? tenantId, Guid userId, NotificationReadState readState = NotificationReadState.UnRead, int maxResultCount = 10); IEnumerable<UserIdentifier> identifiers = null,
CancellationToken cancellationToken = default);
Task ChangeUserNotificationReadStateAsync(Guid? tenantId, Guid userId, long notificationId, NotificationReadState readState);
Task<List<NotificationSubscriptionInfo>> GetUserSubscriptionsAsync(
Guid? tenantId,
Guid userId,
CancellationToken cancellationToken = default);
Task<List<NotificationSubscriptionInfo>> GetUserSubscriptionsAsync(
Guid? tenantId,
string userName,
CancellationToken cancellationToken = default);
Task<bool> IsSubscribedAsync(
Guid? tenantId,
Guid userId,
string notificationName,
CancellationToken cancellationToken = default);
Task InsertNotificationAsync(
NotificationInfo notification,
CancellationToken cancellationToken = default);
Task DeleteNotificationAsync(
NotificationInfo notification,
CancellationToken cancellationToken = default);
Task DeleteNotificationAsync(
int batchCount,
CancellationToken cancellationToken = default);
Task InsertUserNotificationAsync(
NotificationInfo notification,
Guid userId,
CancellationToken cancellationToken = default);
Task InsertUserNotificationsAsync(
NotificationInfo notification,
IEnumerable<Guid> userIds,
CancellationToken cancellationToken = default);
Task DeleteUserNotificationAsync(
Guid? tenantId,
Guid userId,
long notificationId,
CancellationToken cancellationToken = default);
Task<NotificationInfo> GetNotificationOrNullAsync(
Guid? tenantId,
long notificationId,
CancellationToken cancellationToken = default);
Task<List<NotificationInfo>> GetUserNotificationsAsync(
Guid? tenantId,
Guid userId,
NotificationReadState readState = NotificationReadState.UnRead,
int maxResultCount = 10,
CancellationToken cancellationToken = default);
Task<int> GetUserNotificationsCountAsync(
Guid? tenantId,
Guid userId,
string filter = "",
NotificationReadState readState = NotificationReadState.UnRead,
CancellationToken cancellationToken = default);
Task<List<NotificationInfo>> GetUserNotificationsAsync(
Guid? tenantId,
Guid userId,
string filter = "",
string sorting = nameof(NotificationInfo.CreationTime),
bool reverse = true,
NotificationReadState readState = NotificationReadState.UnRead,
int skipCount = 1,
int maxResultCount = 10,
CancellationToken cancellationToken = default);
Task ChangeUserNotificationReadStateAsync(
Guid? tenantId,
Guid userId,
long notificationId,
NotificationReadState readState,
CancellationToken cancellationToken = default);
} }
} }

53
aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/INotificationSubscriptionManager.cs

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace LINGYUN.Abp.Notifications namespace LINGYUN.Abp.Notifications
@ -16,7 +17,11 @@ namespace LINGYUN.Abp.Notifications
/// <param name="userId">用户标识</param> /// <param name="userId">用户标识</param>
/// <param name="notificationName">通知名称</param> /// <param name="notificationName">通知名称</param>
/// <returns></returns> /// <returns></returns>
Task<bool> IsSubscribedAsync(Guid? tenantId, Guid userId, string notificationName); Task<bool> IsSubscribedAsync(
Guid? tenantId,
Guid userId,
string notificationName,
CancellationToken cancellationToken = default);
/// <summary> /// <summary>
/// 订阅通知 /// 订阅通知
/// </summary> /// </summary>
@ -24,7 +29,11 @@ namespace LINGYUN.Abp.Notifications
/// <param name="identifier">用户标识</param> /// <param name="identifier">用户标识</param>
/// <param name="notificationName">通知名称</param> /// <param name="notificationName">通知名称</param>
/// <returns></returns> /// <returns></returns>
Task SubscribeAsync(Guid? tenantId, UserIdentifier identifier, string notificationName); Task SubscribeAsync(
Guid? tenantId,
UserIdentifier identifier,
string notificationName,
CancellationToken cancellationToken = default);
/// <summary> /// <summary>
/// 订阅通知 /// 订阅通知
/// </summary> /// </summary>
@ -32,14 +41,21 @@ namespace LINGYUN.Abp.Notifications
/// <param name="identifiers">用户标识列表</param> /// <param name="identifiers">用户标识列表</param>
/// <param name="notificationName">通知名称</param> /// <param name="notificationName">通知名称</param>
/// <returns></returns> /// <returns></returns>
Task SubscribeAsync(Guid? tenantId, IEnumerable<UserIdentifier> identifiers, string notificationName); Task SubscribeAsync(
Guid? tenantId,
IEnumerable<UserIdentifier> identifiers,
string notificationName,
CancellationToken cancellationToken = default);
/// <summary> /// <summary>
/// 取消所有用户订阅 /// 取消所有用户订阅
/// </summary> /// </summary>
/// <param name="tenantId">租户</param> /// <param name="tenantId">租户</param>
/// <param name="notificationName">通知名称</param> /// <param name="notificationName">通知名称</param>
/// <returns></returns> /// <returns></returns>
Task UnsubscribeAllAsync(Guid? tenantId, string notificationName); Task UnsubscribeAllAsync(
Guid? tenantId,
string notificationName,
CancellationToken cancellationToken = default);
/// <summary> /// <summary>
/// 取消订阅 /// 取消订阅
/// </summary> /// </summary>
@ -47,7 +63,11 @@ namespace LINGYUN.Abp.Notifications
/// <param name="identifier">用户标识</param> /// <param name="identifier">用户标识</param>
/// <param name="notificationName">通知名称</param> /// <param name="notificationName">通知名称</param>
/// <returns></returns> /// <returns></returns>
Task UnsubscribeAsync(Guid? tenantId, UserIdentifier identifier, string notificationName); Task UnsubscribeAsync(
Guid? tenantId,
UserIdentifier identifier,
string notificationName,
CancellationToken cancellationToken = default);
/// <summary> /// <summary>
/// 取消订阅 /// 取消订阅
/// </summary> /// </summary>
@ -55,27 +75,42 @@ namespace LINGYUN.Abp.Notifications
/// <param name="identifiers">用户标识列表</param> /// <param name="identifiers">用户标识列表</param>
/// <param name="notificationName">通知名称</param> /// <param name="notificationName">通知名称</param>
/// <returns></returns> /// <returns></returns>
Task UnsubscribeAsync(Guid? tenantId, IEnumerable<UserIdentifier> identifiers, string notificationName); Task UnsubscribeAsync(
Guid? tenantId,
IEnumerable<UserIdentifier> identifiers,
string notificationName,
CancellationToken cancellationToken = default);
/// <summary> /// <summary>
/// 获取通知被订阅用户列表 /// 获取通知被订阅用户列表
/// </summary> /// </summary>
/// <param name="tenantId">租户</param> /// <param name="tenantId">租户</param>
/// <param name="notificationName">通知名称</param> /// <param name="notificationName">通知名称</param>
/// <param name="identifiers">需要检查的用户列表</param>
/// <returns></returns> /// <returns></returns>
Task<List<NotificationSubscriptionInfo>> GetSubscriptionsAsync(Guid? tenantId, string notificationName); Task<List<NotificationSubscriptionInfo>> GetUsersSubscriptionsAsync(
Guid? tenantId,
string notificationName,
IEnumerable<UserIdentifier> identifiers = null,
CancellationToken cancellationToken = default);
/// <summary> /// <summary>
/// 获取用户订阅列表 /// 获取用户订阅列表
/// </summary> /// </summary>
/// <param name="tenantId">租户</param> /// <param name="tenantId">租户</param>
/// <param name="userId">用户标识</param> /// <param name="userId">用户标识</param>
/// <returns></returns> /// <returns></returns>
Task<List<NotificationSubscriptionInfo>> GetUserSubscriptionsAsync(Guid? tenantId, Guid userId); Task<List<NotificationSubscriptionInfo>> GetUserSubscriptionsAsync(
Guid? tenantId,
Guid userId,
CancellationToken cancellationToken = default);
/// <summary> /// <summary>
/// 获取用户订阅列表 /// 获取用户订阅列表
/// </summary> /// </summary>
/// <param name="tenantId">租户</param> /// <param name="tenantId">租户</param>
/// <param name="userName">用户名</param> /// <param name="userName">用户名</param>
/// <returns></returns> /// <returns></returns>
Task<List<NotificationSubscriptionInfo>> GetUserSubscriptionsAsync(Guid? tenantId, string userName); Task<List<NotificationSubscriptionInfo>> GetUserSubscriptionsAsync(
Guid? tenantId,
string userName,
CancellationToken cancellationToken = default);
} }
} }

220
aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/Internal/DefaultNotificationDispatcher.cs

@ -1,220 +0,0 @@
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp.BackgroundJobs;
using Volo.Abp.EventBus.Distributed;
namespace LINGYUN.Abp.Notifications.Internal
{
/// <summary>
/// Implements <see cref="INotificationDispatcher"/>.
/// </summary>
internal class DefaultNotificationDispatcher : INotificationDispatcher
{
/// <summary>
/// Reference to <see cref="ILogger<DefaultNotificationDispatcher>"/>.
/// </summary>
public ILogger<DefaultNotificationDispatcher> Logger { get; set; }
/// <summary>
/// Reference to <see cref="IDistributedEventBus"/>.
/// </summary>
public IDistributedEventBus DistributedEventBus { get; set; }
/// <summary>
/// Reference to <see cref="AbpNotificationOptions"/>.
/// </summary>
private readonly AbpNotificationOptions _notificationOptions;
/// <summary>
/// Reference to <see cref="IBackgroundJobManager"/>.
/// </summary>
private readonly IBackgroundJobManager _backgroundJobManager;
/// <summary>
/// Reference to <see cref="INotificationStore"/>.
/// </summary>
private readonly INotificationStore _notificationStore;
/// <summary>
/// Reference to <see cref="INotificationDefinitionManager"/>.
/// </summary>
private readonly INotificationDefinitionManager _notificationDefinitionManager;
/// <summary>
/// Reference to <see cref="INotificationPublishProviderManager"/>.
/// </summary>
private readonly INotificationPublishProviderManager _notificationPublishProviderManager;
/// <summary>
/// Initializes a new instance of the <see cref="DefaultNotificationDispatcher"/> class.
/// </summary>
public DefaultNotificationDispatcher(
IBackgroundJobManager backgroundJobManager,
IOptions<AbpNotificationOptions> options,
INotificationStore notificationStore,
INotificationDefinitionManager notificationDefinitionManager,
INotificationPublishProviderManager notificationPublishProviderManager)
{
_backgroundJobManager = backgroundJobManager;
_notificationOptions = options.Value;
_notificationStore = notificationStore;
_notificationDefinitionManager = notificationDefinitionManager;
_notificationPublishProviderManager = notificationPublishProviderManager;
DistributedEventBus = NullDistributedEventBus.Instance;
Logger = NullLogger<DefaultNotificationDispatcher>.Instance;
}
/// <summary>
/// 发送通知
/// </summary>
/// <param name="notificationName">通知名称</param>
/// <param name="data">通知数据</param>
/// <param name="tenantId">租户</param>
/// <param name="notificationSeverity">级别</param>
/// <returns></returns>
public virtual async Task DispatchAsync(NotificationName notificationName, NotificationData data, Guid? tenantId = null,
NotificationSeverity notificationSeverity = NotificationSeverity.Info)
{
// 获取自定义的通知
var defineNotification = _notificationDefinitionManager.Get(notificationName.CateGory);
//// 没有定义的通知,应该也要能发布、订阅,
//// 比如订单之类的,是以订单编号为通知名称,这是动态的,没法自定义
//if(defineNotification == null)
//{
// defineNotification = new NotificationDefinition(notificationName.CateGory);
//}
var notificationInfo = new NotificationInfo
{
CateGory = notificationName.CateGory,
Name = notificationName.Name,
CreationTime = DateTime.Now,
NotificationSeverity = notificationSeverity,
Lifetime = defineNotification.NotificationLifetime,
NotificationType = defineNotification.NotificationType,
TenantId = tenantId,
Data = data
};
var providers = Enumerable
.Reverse(_notificationPublishProviderManager.Providers);
if (defineNotification.Providers.Any())
{
providers = providers.Where(p => defineNotification.Providers.Contains(p.Name));
}
await PublishFromProvidersAsync(providers, notificationInfo);
if (notificationInfo.Lifetime == NotificationLifetime.OnlyOne)
{
// 一次性通知在发送完成后就取消用户订阅
await _notificationStore.DeleteAllUserSubscriptionAsync(notificationInfo.TenantId,
notificationInfo.Name);
}
}
/// <summary>
/// 发送通知事件
/// </summary>
/// <param name="notificationName"></param>
/// <param name="data"></param>
/// <param name="tenantId"></param>
/// <param name="notificationSeverity"></param>
/// <returns></returns>
public virtual async Task DispatchEventAsync(NotificationName notificationName, NotificationData data, Guid? tenantId = null,
NotificationSeverity notificationSeverity = NotificationSeverity.Info)
{
// 获取自定义的通知
var defineNotification = _notificationDefinitionManager.Get(notificationName.CateGory);
var notificationEventData = new NotificationEventData
{
CateGory = notificationName.CateGory,
Name = notificationName.Name,
CreationTime = DateTime.Now,
NotificationSeverity = notificationSeverity,
Lifetime = defineNotification.NotificationLifetime,
NotificationType = defineNotification.NotificationType,
TenantId = tenantId,
Data = data
};
// 发布分布式通知事件,让消息中心统一处理
await DistributedEventBus.PublishAsync(notificationEventData);
}
/// <summary>
/// 指定提供者发布通知
/// </summary>
/// <param name="providers">提供者列表</param>
/// <param name="notificationInfo">通知信息</param>
/// <returns></returns>
protected async Task PublishFromProvidersAsync(IEnumerable<INotificationPublishProvider> providers,
NotificationInfo notificationInfo)
{
Logger.LogDebug($"Persistent notification {notificationInfo.Name}");
// 持久化通知
await _notificationStore.InsertNotificationAsync(notificationInfo);
Logger.LogDebug($"Gets a list of user subscriptions {notificationInfo.Name}");
// 获取用户订阅列表
var userSubscriptions = await _notificationStore.GetSubscriptionsAsync(notificationInfo.TenantId, notificationInfo.Name);
Logger.LogDebug($"Persistent user notifications {notificationInfo.Name}");
// 持久化用户通知
var subscriptionUserIdentifiers = userSubscriptions.Select(us => new UserIdentifier(us.UserId, us.UserName));
await _notificationStore.InsertUserNotificationsAsync(notificationInfo,
subscriptionUserIdentifiers.Select(u => u.UserId));
// 发布通知
foreach (var provider in providers)
{
await PublishAsync(provider, notificationInfo, subscriptionUserIdentifiers);
}
// TODO: 需要计算队列大小,根据情况是否需要并行发布消息
//Parallel.ForEach(providers, async (provider) =>
//{
// await PublishAsync(provider, notificationInfo, subscriptionUserIdentifiers);
//});
}
/// <summary>
/// 发布通知
/// </summary>
/// <param name="provider">通知发布者</param>
/// <param name="notificationInfo">通知信息</param>
/// <param name="subscriptionUserIdentifiers">订阅用户列表</param>
/// <returns></returns>
protected async Task PublishAsync(INotificationPublishProvider provider, NotificationInfo notificationInfo,
IEnumerable<UserIdentifier> subscriptionUserIdentifiers)
{
try
{
Logger.LogDebug($"Sending notification with provider {provider.Name}");
var notifacationDataMapping = _notificationOptions.NotificationDataMappings
.GetMapItemOrNull(notificationInfo.CateGory, provider.Name);
if (notifacationDataMapping != null)
{
notificationInfo.Data = notifacationDataMapping.MappingFunc(notificationInfo.Data);
}
// 发布
await provider.PublishAsync(notificationInfo, subscriptionUserIdentifiers);
Logger.LogDebug($"Send notification {notificationInfo.Name} with provider {provider.Name} was successful");
}
catch (Exception ex)
{
Logger.LogWarning($"Send notification error with provider {provider.Name}");
Logger.LogWarning($"Error message:{ex.Message}");
Logger.LogTrace(ex, $"Send notification error with provider { provider.Name}");
Logger.LogDebug($"Send notification error, notification {notificationInfo.Name} entry queue");
// 发送失败的消息进入后台队列
await _backgroundJobManager.EnqueueAsync(
new NotificationPublishJobArgs(notificationInfo.GetId(),
provider.GetType().AssemblyQualifiedName,
subscriptionUserIdentifiers.ToList(),
notificationInfo.TenantId));
}
}
}
}

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

@ -0,0 +1,78 @@
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
using Volo.Abp.EventBus.Distributed;
namespace LINGYUN.Abp.Notifications
{
public class NotificationSender : INotificationSender, ITransientDependency
{
/// <summary>
/// Reference to <see cref="ILogger<NotificationSender>"/>.
/// </summary>
public ILogger<NotificationSender> Logger { get; set; }
/// <summary>
/// Reference to <see cref="IDistributedEventBus"/>.
/// </summary>
public IDistributedEventBus DistributedEventBus { get; }
public NotificationSender(
IDistributedEventBus distributedEventBus)
{
DistributedEventBus = distributedEventBus;
Logger = NullLogger<NotificationSender>.Instance;
}
public async Task SendNofiterAsync(
string name,
NotificationData data,
UserIdentifier user = null,
Guid? tenantId = null,
NotificationSeverity severity = NotificationSeverity.Info)
{
if (user == null)
{
await PublishNofiterAsync(name, data, null, tenantId, severity);
}
else
{
await PublishNofiterAsync(name, data, new List<UserIdentifier> { user }, tenantId, severity);
}
}
public async Task SendNofitersAsync(
string name,
NotificationData data,
IEnumerable<UserIdentifier> users = null,
Guid? tenantId = null,
NotificationSeverity severity = NotificationSeverity.Info)
{
await PublishNofiterAsync(name, data, users, tenantId, severity);
}
protected async Task PublishNofiterAsync(
string name,
NotificationData data,
IEnumerable<UserIdentifier> users = null,
Guid? tenantId = null,
NotificationSeverity severity = NotificationSeverity.Info)
{
await DistributedEventBus
.PublishAsync(
new NotificationEventData
{
TenantId = tenantId,
Users = users?.ToList(),
Name = name,
Data = data,
CreationTime = DateTime.Now,
Severity = severity
});
}
}
}

72
aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/Internal/NotificationSubscriptionManager.cs

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
@ -15,56 +16,89 @@ namespace LINGYUN.Abp.Notifications.Internal
_store = store; _store = store;
} }
public virtual async Task<List<NotificationSubscriptionInfo>> GetSubscriptionsAsync(Guid? tenantId, string notificationName) public virtual async Task<List<NotificationSubscriptionInfo>> GetUsersSubscriptionsAsync(
Guid? tenantId,
string notificationName,
IEnumerable<UserIdentifier> identifiers = null,
CancellationToken cancellationToken = default)
{ {
return await _store.GetSubscriptionsAsync(tenantId, notificationName); return await _store.GetUserSubscriptionsAsync(tenantId, notificationName, identifiers, cancellationToken);
} }
public virtual async Task<List<NotificationSubscriptionInfo>> GetUserSubscriptionsAsync(Guid? tenantId, Guid userId) public virtual async Task<List<NotificationSubscriptionInfo>> GetUserSubscriptionsAsync(
Guid? tenantId,
Guid userId,
CancellationToken cancellationToken = default)
{ {
return await _store.GetUserSubscriptionsAsync(tenantId, userId); return await _store.GetUserSubscriptionsAsync(tenantId, userId, cancellationToken);
} }
public virtual async Task<List<NotificationSubscriptionInfo>> GetUserSubscriptionsAsync(Guid? tenantId, string userName) public virtual async Task<List<NotificationSubscriptionInfo>> GetUserSubscriptionsAsync(
Guid? tenantId,
string userName,
CancellationToken cancellationToken = default)
{ {
return await _store.GetUserSubscriptionsAsync(tenantId, userName); return await _store.GetUserSubscriptionsAsync(tenantId, userName, cancellationToken);
} }
public virtual async Task<bool> IsSubscribedAsync(Guid? tenantId, Guid userId, string notificationName) public virtual async Task<bool> IsSubscribedAsync(
Guid? tenantId,
Guid userId,
string notificationName,
CancellationToken cancellationToken = default)
{ {
return await _store.IsSubscribedAsync(tenantId, userId, notificationName); return await _store.IsSubscribedAsync(tenantId, userId, notificationName, cancellationToken);
} }
public virtual async Task SubscribeAsync(Guid? tenantId, UserIdentifier identifier, string notificationName) public virtual async Task SubscribeAsync(
Guid? tenantId,
UserIdentifier identifier,
string notificationName,
CancellationToken cancellationToken = default)
{ {
if (await IsSubscribedAsync(tenantId, identifier.UserId, notificationName)) if (await IsSubscribedAsync(tenantId, identifier.UserId, notificationName, cancellationToken))
{ {
return; return;
} }
await _store.InsertUserSubscriptionAsync(tenantId, identifier, notificationName); await _store.InsertUserSubscriptionAsync(tenantId, identifier, notificationName, cancellationToken);
} }
public virtual async Task SubscribeAsync(Guid? tenantId, IEnumerable<UserIdentifier> identifiers, string notificationName) public virtual async Task SubscribeAsync(
Guid? tenantId,
IEnumerable<UserIdentifier> identifiers,
string notificationName,
CancellationToken cancellationToken = default)
{ {
foreach(var identifier in identifiers) foreach(var identifier in identifiers)
{ {
await SubscribeAsync(tenantId, identifier, notificationName); await SubscribeAsync(tenantId, identifier, notificationName, cancellationToken);
} }
} }
public virtual async Task UnsubscribeAsync(Guid? tenantId, UserIdentifier identifier, string notificationName) public virtual async Task UnsubscribeAsync(
Guid? tenantId,
UserIdentifier identifier,
string notificationName,
CancellationToken cancellationToken = default)
{ {
await _store.DeleteUserSubscriptionAsync(tenantId, identifier.UserId, notificationName); await _store.DeleteUserSubscriptionAsync(tenantId, identifier.UserId, notificationName, cancellationToken);
} }
public virtual async Task UnsubscribeAllAsync(Guid? tenantId, string notificationName) public virtual async Task UnsubscribeAllAsync(
Guid? tenantId,
string notificationName,
CancellationToken cancellationToken = default)
{ {
await _store.DeleteAllUserSubscriptionAsync(tenantId, notificationName); await _store.DeleteAllUserSubscriptionAsync(tenantId, notificationName, cancellationToken);
} }
public virtual async Task UnsubscribeAsync(Guid? tenantId, IEnumerable<UserIdentifier> identifiers, string notificationName) public virtual async Task UnsubscribeAsync(
Guid? tenantId,
IEnumerable<UserIdentifier> identifiers,
string notificationName,
CancellationToken cancellationToken = default)
{ {
await _store.DeleteUserSubscriptionAsync(tenantId, identifiers, notificationName); await _store.DeleteUserSubscriptionAsync(tenantId, identifiers, notificationName, cancellationToken);
} }
} }
} }

23
aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/LocalizableStringInfo.cs

@ -0,0 +1,23 @@
using System.Collections.Generic;
namespace LINGYUN.Abp.Notifications
{
public class LocalizableStringInfo
{
public string ResourceName { get; }
public string Name { get; }
public Dictionary<object, object> Values { get; }
public LocalizableStringInfo(
string resourceName,
string name,
Dictionary<object, object> values = null)
{
ResourceName = resourceName;
Name = name;
Values = values;
}
}
}

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

@ -8,14 +8,11 @@ namespace LINGYUN.Abp.Notifications
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// TODO: 2020-10-29 针对不同语言的用户,如果在发布时期就本地化语言是错误的设计 /// TODO: 2020-10-29 针对不同语言的用户,如果在发布时期就本地化语言是错误的设计
/// 把通知的标题和内容设计为 <see cref="Volo.Abp.Validation.StringValues.LocalizableStringInfo"/> 让客户端自行本地化 /// 把通知的标题和内容设计为 <see cref="LocalizableStringInfo"/> 让客户端自行本地化
/// </remarks> /// </remarks>
public class NotificationData public class NotificationData
{ {
public const string NotificationKey = "N:G"; public const string LocalizerKey = "localizer";
public const string UserIdNotificationKey = "N:UI";
public const string UserNameNotificationKey = "N:UN";
public const string TenantNotificationKey = "N:T";
public virtual string Type => GetType().FullName; public virtual string Type => GetType().FullName;
public object this[string key] public object this[string key]
@ -55,30 +52,35 @@ namespace LINGYUN.Abp.Notifications
public NotificationData() public NotificationData()
{ {
_properties = new Dictionary<string, object>(); _properties = new Dictionary<string, object>();
TrySetData(LocalizerKey, false);
} }
/// <summary>
public static NotificationData CreateNotificationData() /// 写入本地化的消息数据
{ /// </summary>
var data = new NotificationData(); /// <param name="title"></param>
data.TrySetData(NotificationKey, "AbpNotification"); /// <param name="message"></param>
return data; /// <param name="createTime"></param>
} /// <param name="formUser"></param>
/// <param name="description"></param>
public static NotificationData CreateUserNotificationData(Guid userId, string userName) /// <returns></returns>
{ public NotificationData WriteLocalizedData(
var data = new NotificationData(); LocalizableStringInfo title,
data.TrySetData(UserIdNotificationKey, userId); LocalizableStringInfo message,
data.TrySetData(UserNameNotificationKey, userName); DateTime createTime,
return data; string formUser,
} LocalizableStringInfo description = null)
public static NotificationData CreateTenantNotificationData(Guid tenantId)
{ {
var data = new NotificationData(); TrySetData("title", title);
data.TrySetData(TenantNotificationKey, tenantId); TrySetData("message", message);
return data; TrySetData("formUser", formUser);
TrySetData("createTime", createTime);
TrySetData(LocalizerKey, true);
if (description != null)
{
TrySetData("description", description);
}
return this;
} }
/// <summary> /// <summary>
/// 写入标准数据 /// 写入标准数据
/// </summary> /// </summary>
@ -86,13 +88,16 @@ namespace LINGYUN.Abp.Notifications
/// <param name="message">内容</param> /// <param name="message">内容</param>
/// <param name="createTime">创建时间</param> /// <param name="createTime">创建时间</param>
/// <param name="formUser">来源用户</param> /// <param name="formUser">来源用户</param>
/// <param name="description">附加说明</param>
/// <returns></returns> /// <returns></returns>
public NotificationData WriteStandardData(string title, string message, DateTime createTime, string formUser) public NotificationData WriteStandardData(string title, string message, DateTime createTime, string formUser, string description = "")
{ {
TrySetData("title", title); TrySetData("title", title);
TrySetData("message", message); TrySetData("message", message);
TrySetData("description", description);
TrySetData("formUser", formUser); TrySetData("formUser", formUser);
TrySetData("createTime", createTime); TrySetData("createTime", createTime);
TrySetData(LocalizerKey, false);
return this; return this;
} }
/// <summary> /// <summary>
@ -105,6 +110,7 @@ namespace LINGYUN.Abp.Notifications
public NotificationData WriteStandardData(string prefix, string key, object value) public NotificationData WriteStandardData(string prefix, string key, object value)
{ {
TrySetData(string.Concat(prefix, key), value); TrySetData(string.Concat(prefix, key), value);
TrySetData(LocalizerKey, false);
return this; return this;
} }
/// <summary> /// <summary>
@ -117,8 +123,10 @@ namespace LINGYUN.Abp.Notifications
var data = new NotificationData(); var data = new NotificationData();
data.TrySetData("title", sourceData.TryGetData("title")); data.TrySetData("title", sourceData.TryGetData("title"));
data.TrySetData("message", sourceData.TryGetData("message")); data.TrySetData("message", sourceData.TryGetData("message"));
data.TrySetData("description", sourceData.TryGetData("description"));
data.TrySetData("formUser", sourceData.TryGetData("formUser")); data.TrySetData("formUser", sourceData.TryGetData("formUser"));
data.TrySetData("createTime", sourceData.TryGetData("createTime")); data.TrySetData("createTime", sourceData.TryGetData("createTime"));
data.TrySetData(LocalizerKey, sourceData.TryGetData(LocalizerKey));
return data; return data;
} }
/// <summary> /// <summary>
@ -154,29 +162,20 @@ namespace LINGYUN.Abp.Notifications
{ {
if (value != null && !Properties.ContainsKey(key)) if (value != null && !Properties.ContainsKey(key))
{ {
Properties[key] = value; Properties.Add(key, value);
} }
Properties[key] = value;
} }
/// <summary>
public bool HasUserNotification(out Guid userId, out string userName) /// 需要本地化
{ /// </summary>
userName = ""; /// <returns></returns>
if (Properties.TryGetValue(UserIdNotificationKey, out object userKey)) public bool NeedLocalizer()
{
userId = (Guid)userKey;
var name = TryGetData(UserNameNotificationKey);
userName = name?.ToString() ?? userName;
return true;
}
return false;
}
public bool HasTenantNotification(out Guid tenantId)
{ {
if (Properties.TryGetValue(TenantNotificationKey, out object tenantKey)) var localizer = TryGetData(LocalizerKey);
if (localizer != null && localizer is bool needLocalizer)
{ {
tenantId = (Guid)tenantKey; return needLocalizer;
return true;
} }
return false; return false;
} }

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

@ -0,0 +1,31 @@
using Newtonsoft.Json;
namespace LINGYUN.Abp.Notifications
{
public class NotificationDataConverter
{
public static NotificationData Convert(NotificationData notificationData)
{
if (notificationData != null)
{
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("description", out object description) && description != null)
{
notificationData.TrySetData("description", JsonConvert.DeserializeObject<LocalizableStringInfo>(description.ToString()));
}
}
}
else
{
notificationData = new NotificationData();
}
return notificationData;
}
}
}

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

@ -6,13 +6,13 @@ namespace LINGYUN.Abp.Notifications
{ {
public class NotificationDataMappingDictionary : Dictionary<string, List<NotificationDataMappingDictionaryItem>> public class NotificationDataMappingDictionary : Dictionary<string, List<NotificationDataMappingDictionaryItem>>
{ {
public void Mapping(string cateGory, string provider, Func<NotificationData, NotificationData> func) public void Mapping(string name, string provider, Func<NotificationData, NotificationData> func)
{ {
if (ContainsKey(cateGory)) if (ContainsKey(name))
{ {
this[cateGory] = new List<NotificationDataMappingDictionaryItem>(); this[name] = new List<NotificationDataMappingDictionaryItem>();
} }
this[cateGory].Add(new NotificationDataMappingDictionaryItem(provider, func)); this[name].Add(new NotificationDataMappingDictionaryItem(provider, func));
} }
public void MappingAll(string provider, Func<NotificationData, NotificationData> func) public void MappingAll(string provider, Func<NotificationData, NotificationData> func)
@ -23,11 +23,11 @@ namespace LINGYUN.Abp.Notifications
} }
} }
public NotificationDataMappingDictionaryItem GetMapItemOrNull(string cateGory, string provider) public NotificationDataMappingDictionaryItem GetMapItemOrNull(string name, string provider)
{ {
if (ContainsKey(cateGory)) if (ContainsKey(name))
{ {
return this[cateGory].FirstOrDefault(map => map.Provider.Equals(provider)); return this[name].FirstOrDefault(map => map.Provider.Equals(provider));
} }
return null; return null;
} }

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

@ -3,17 +3,11 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using Volo.Abp; using Volo.Abp;
using Volo.Abp.Localization; using Volo.Abp.Localization;
using Volo.Abp.MultiTenancy;
/* /*
* * 2020-10-29
* ,,,Catalog * INotificationSender指定接收者,,,()
* Prefix
*
* TODO: 2020-08-26 ?
* 宿,
* NotificationData[FormUser]
* NotificationData[FormTenant]
* NotificationData[FormGlobal]
*/ */
namespace LINGYUN.Abp.Notifications namespace LINGYUN.Abp.Notifications
@ -21,10 +15,10 @@ namespace LINGYUN.Abp.Notifications
public class NotificationDefinition public class NotificationDefinition
{ {
/// <summary> /// <summary>
/// 通知类目 /// 通知名称
/// </summary> /// </summary>
[NotNull] [NotNull]
public string CateGory { get; set; } public string Name { get; set; }
/// <summary> /// <summary>
/// 通知显示名称 /// 通知显示名称
/// </summary> /// </summary>
@ -58,15 +52,15 @@ namespace LINGYUN.Abp.Notifications
public List<string> Providers { get; } public List<string> Providers { get; }
public NotificationDefinition( public NotificationDefinition(
string category, string name,
ILocalizableString displayName = null, ILocalizableString displayName = null,
ILocalizableString description = null, ILocalizableString description = null,
NotificationType notificationType = NotificationType.Application, NotificationType notificationType = NotificationType.Application,
NotificationLifetime lifetime = NotificationLifetime.Persistent, NotificationLifetime lifetime = NotificationLifetime.Persistent,
bool allowSubscriptionToClients = false) bool allowSubscriptionToClients = false)
{ {
CateGory = category; Name = name;
DisplayName = displayName ?? new FixedLocalizableString(category); DisplayName = displayName ?? new FixedLocalizableString(name);
Description = description; Description = description;
NotificationLifetime = lifetime; NotificationLifetime = lifetime;
NotificationType = notificationType; NotificationType = notificationType;
@ -84,5 +78,10 @@ namespace LINGYUN.Abp.Notifications
return this; return this;
} }
public override string ToString()
{
return $"[{nameof(NotificationDefinition)} {Name}]";
}
} }
} }

46
aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationDefinitionContext.cs

@ -1,33 +1,57 @@
using System; using JetBrains.Annotations;
using System.Collections.Generic; using System.Collections.Generic;
using Volo.Abp;
using Volo.Abp.Localization;
using Volo.Abp.MultiTenancy;
namespace LINGYUN.Abp.Notifications namespace LINGYUN.Abp.Notifications
{ {
public class NotificationDefinitionContext : INotificationDefinitionContext public class NotificationDefinitionContext : INotificationDefinitionContext
{ {
protected Dictionary<string, NotificationDefinition> Notifications { get; } internal Dictionary<string, NotificationGroupDefinition> Groups { get; }
public NotificationDefinitionContext(Dictionary<string, NotificationDefinition> notifications) public NotificationDefinitionContext()
{ {
Notifications = notifications; Groups = new Dictionary<string, NotificationGroupDefinition>();
} }
public void Add(params NotificationDefinition[] definitions) public NotificationGroupDefinition AddGroup(
[NotNull] string name,
ILocalizableString displayName = null,
bool allowSubscriptionToClients = true)
{ {
if (definitions.IsNullOrEmpty()) Check.NotNull(name, nameof(name));
if (Groups.ContainsKey(name))
{ {
return; throw new AbpException($"There is already an existing notification group with name: {name}");
} }
foreach (var definition in definitions) return Groups[name] = new NotificationGroupDefinition(name, displayName, allowSubscriptionToClients);
}
public NotificationGroupDefinition GetGroupOrNull(string name)
{
Check.NotNull(name, nameof(name));
if (!Groups.ContainsKey(name))
{ {
Notifications[definition.CateGory] = definition; return null;
} }
return Groups[name];
} }
public NotificationDefinition GetOrNull(string category) public void RemoveGroup(string name)
{ {
return Notifications.GetOrDefault(category); Check.NotNull(name, nameof(name));
if (!Groups.ContainsKey(name))
{
throw new AbpException($"Undefined notification group: '{name}'.");
}
Groups.Remove(name);
} }
} }
} }

78
aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationDefinitionManager.cs

@ -1,5 +1,4 @@
using JetBrains.Annotations; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@ -12,51 +11,88 @@ namespace LINGYUN.Abp.Notifications
{ {
public class NotificationDefinitionManager : INotificationDefinitionManager, ISingletonDependency public class NotificationDefinitionManager : INotificationDefinitionManager, ISingletonDependency
{ {
protected Lazy<IDictionary<string, NotificationDefinition>> NotificationDefinitions { get; }
protected AbpNotificationOptions Options { get; } protected AbpNotificationOptions Options { get; }
protected IServiceProvider ServiceProvider { get; } protected IDictionary<string, NotificationGroupDefinition> NotificationGroupDefinitions => _lazyNotificationGroupDefinitions.Value;
private readonly Lazy<Dictionary<string, NotificationGroupDefinition>> _lazyNotificationGroupDefinitions;
protected IDictionary<string, NotificationDefinition> NotificationDefinitions => _lazyNotificationDefinitions.Value;
private readonly Lazy<Dictionary<string, NotificationDefinition>> _lazyNotificationDefinitions;
private readonly IServiceScopeFactory _serviceScopeFactory;
public NotificationDefinitionManager( public NotificationDefinitionManager(
IOptions<AbpNotificationOptions> options, IOptions<AbpNotificationOptions> options,
IServiceProvider serviceProvider) IServiceScopeFactory serviceScopeFactory)
{ {
ServiceProvider = serviceProvider; _serviceScopeFactory = serviceScopeFactory;
Options = options.Value; Options = options.Value;
NotificationDefinitions = new Lazy<IDictionary<string, NotificationDefinition>>(CreateNotificationDefinitions, true); _lazyNotificationDefinitions = new Lazy<Dictionary<string, NotificationDefinition>>(
CreateNotificationDefinitions,
isThreadSafe: true
);
_lazyNotificationGroupDefinitions = new Lazy<Dictionary<string, NotificationGroupDefinition>>(
CreateNotificationGroupDefinitions,
isThreadSafe: true
);
} }
public virtual NotificationDefinition Get([NotNull] string category) public virtual NotificationDefinition Get(string name)
{ {
Check.NotNull(category, nameof(category)); Check.NotNull(name, nameof(name));
var notification = GetOrNull(category); var feature = GetOrNull(name);
if (notification == null) if (feature == null)
{ {
throw new AbpException("Undefined notification category: " + category); throw new AbpException("Undefined notification: " + name);
} }
return notification; return feature;
} }
public virtual IReadOnlyList<NotificationDefinition> GetAll() public virtual IReadOnlyList<NotificationDefinition> GetAll()
{ {
return NotificationDefinitions.Value.Values.ToImmutableList(); return NotificationDefinitions.Values.ToImmutableList();
}
public virtual NotificationDefinition GetOrNull(string name)
{
return NotificationDefinitions.GetOrDefault(name);
} }
public virtual NotificationDefinition GetOrNull(string category) public IReadOnlyList<NotificationGroupDefinition> GetGroups()
{ {
return NotificationDefinitions.Value.GetOrDefault(category); return NotificationGroupDefinitions.Values.ToImmutableList();
} }
protected virtual IDictionary<string, NotificationDefinition> CreateNotificationDefinitions() protected virtual Dictionary<string, NotificationDefinition> CreateNotificationDefinitions()
{ {
var notifications = new Dictionary<string, NotificationDefinition>(); var notifications = new Dictionary<string, NotificationDefinition>();
using (var scope = ServiceProvider.CreateScope()) foreach (var groupDefinition in NotificationGroupDefinitions.Values)
{
foreach (var notification in groupDefinition.Notifications)
{
if (notifications.ContainsKey(notification.Name))
{
throw new AbpException("Duplicate notification name: " + notification.Name);
}
notifications[notification.Name] = notification;
}
}
return notifications;
}
protected virtual Dictionary<string, NotificationGroupDefinition> CreateNotificationGroupDefinitions()
{
var context = new NotificationDefinitionContext();
using (var scope = _serviceScopeFactory.CreateScope())
{ {
var providers = Options var providers = Options
.DefinitionProviders .DefinitionProviders
@ -65,11 +101,11 @@ namespace LINGYUN.Abp.Notifications
foreach (var provider in providers) foreach (var provider in providers)
{ {
provider.Define(new NotificationDefinitionContext(notifications)); provider.Define(context);
} }
} }
return notifications; return context.Groups;
} }
} }
} }

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

@ -1,38 +1,20 @@
using System; using System;
using System.Collections.Generic;
using Volo.Abp.MultiTenancy;
namespace LINGYUN.Abp.Notifications namespace LINGYUN.Abp.Notifications
{ {
public class NotificationEventData public class NotificationEventData : IMultiTenant
{ {
public Guid? TenantId { get; set; } public Guid? TenantId { get; set; }
public string CateGory { get; set; }
public string Name { get; set; } public string Name { get; set; }
public string Id { get; set; }
public NotificationData Data { get; set; } public NotificationData Data { get; set; }
public DateTime CreationTime { get; set; } public DateTime CreationTime { get; set; }
public NotificationLifetime Lifetime { get; set; } public NotificationSeverity Severity { get; set; }
public NotificationType NotificationType { get; set; } public List<UserIdentifier> Users { get; set; }
public NotificationSeverity NotificationSeverity { get; set; }
public NotificationEventData() public NotificationEventData()
{ {
Users = new List<UserIdentifier>();
}
public NotificationInfo ToNotificationInfo()
{
return new NotificationInfo
{
NotificationSeverity = NotificationSeverity,
CreationTime = CreationTime,
Data = Data,
Id = Id,
Name = Name,
CateGory = CateGory,
NotificationType = NotificationType,
Lifetime = Lifetime,
TenantId = TenantId
};
} }
} }
} }

70
aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationGroupDefinition.cs

@ -0,0 +1,70 @@
using JetBrains.Annotations;
using System.Collections.Generic;
using System.Collections.Immutable;
using Volo.Abp;
using Volo.Abp.Localization;
using Volo.Abp.MultiTenancy;
namespace LINGYUN.Abp.Notifications
{
public class NotificationGroupDefinition
{
/// <summary>
/// 通知组名称
/// </summary>
[NotNull]
public string Name { get; set; }
/// <summary>
/// 通知组显示名称
/// </summary>
[NotNull]
public ILocalizableString DisplayName
{
get => _displayName;
set => _displayName = Check.NotNull(value, nameof(value));
}
private ILocalizableString _displayName;
/// <summary>
/// 通知组说明
/// </summary>
[CanBeNull]
public ILocalizableString Description { get; set; }
public bool AllowSubscriptionToClients { get; set; }
public IReadOnlyList<NotificationDefinition> Notifications => _notifications.ToImmutableList();
private readonly List<NotificationDefinition> _notifications;
protected internal NotificationGroupDefinition(
string name,
ILocalizableString displayName = null,
bool allowSubscriptionToClients = false)
{
Name = name;
DisplayName = displayName ?? new FixedLocalizableString(Name);
AllowSubscriptionToClients = allowSubscriptionToClients;
_notifications = new List<NotificationDefinition>();
}
public virtual NotificationDefinition AddNotification(
string name,
ILocalizableString displayName = null,
ILocalizableString description = null,
NotificationType notificationType = NotificationType.Application,
NotificationLifetime lifetime = NotificationLifetime.Persistent,
bool allowSubscriptionToClients = false)
{
var notification = new NotificationDefinition(
name,
displayName,
description,
notificationType,
lifetime,
allowSubscriptionToClients
);
_notifications.Add(notification);
return notification;
}
}
}

30
aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationInfo.cs

@ -6,53 +6,33 @@ namespace LINGYUN.Abp.Notifications
{ {
public Guid? TenantId { get; set; } public Guid? TenantId { get; set; }
public string Name { get; set; } public string Name { get; set; }
public string CateGory { get; set; }
public string Id { get; set; } public string Id { get; set; }
public NotificationData Data { get; set; } public NotificationData Data { get; set; }
public DateTime CreationTime { get; set; } public DateTime CreationTime { get; set; }
public NotificationLifetime Lifetime { get; set; } public NotificationLifetime Lifetime { get; set; }
public NotificationType NotificationType { get; set; } public NotificationType Type { get; set; }
public NotificationSeverity NotificationSeverity { get; set; } public NotificationSeverity Severity { get; set; }
public NotificationInfo() public NotificationInfo()
{ {
Data = new NotificationData(); Data = new NotificationData();
Lifetime = NotificationLifetime.Persistent; Lifetime = NotificationLifetime.Persistent;
NotificationType = NotificationType.Application; Type = NotificationType.Application;
NotificationSeverity = NotificationSeverity.Info; Severity = NotificationSeverity.Info;
CreationTime = DateTime.Now; CreationTime = DateTime.Now;
} }
public long SetId(long id) public void SetId(long id)
{ {
if (Id.IsNullOrWhiteSpace()) if (Id.IsNullOrWhiteSpace())
{ {
Id = id.ToString(); Id = id.ToString();
return id;
} }
return GetId();
} }
public long GetId() public long GetId()
{ {
return long.Parse(Id); return long.Parse(Id);
} }
public NotificationEventData ToNotificationEventData()
{
return new NotificationEventData
{
NotificationSeverity = NotificationSeverity,
CreationTime = CreationTime,
Data = Data,
Id = Id,
Name = Name,
CateGory = CateGory,
Lifetime = Lifetime,
NotificationType = NotificationType,
TenantId = TenantId
};
}
} }
} }

14
aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationName.cs

@ -1,14 +0,0 @@
namespace LINGYUN.Abp.Notifications
{
public class NotificationName
{
public string CateGory { get; }
public string Name { get; }
public NotificationName(string cateGory, string name)
{
Name = name;
CateGory = cateGory;
}
}
}

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

@ -1,15 +0,0 @@
namespace LINGYUN.Abp.Notifications
{
public static class NotificationNameNormalizer
{
public static NotificationName NormalizerName(string name)
{
return new NotificationName(name, name);
}
public static NotificationName NormalizerName(string category, string name)
{
var notifyName = string.Concat(category, ":", name);
return new NotificationName(category, notifyName);
}
}
}

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

@ -30,8 +30,10 @@ namespace LINGYUN.Abp.Notifications
if (ServiceProvider.GetRequiredService(providerType) is INotificationPublishProvider publishProvider) if (ServiceProvider.GetRequiredService(providerType) is INotificationPublishProvider publishProvider)
{ {
var notification = await Store.GetNotificationOrNullAsync(args.TenantId, args.NotificationId); var notification = await Store.GetNotificationOrNullAsync(args.TenantId, args.NotificationId);
notification.Data = NotificationDataConverter.Convert(notification.Data);
var notifacationDataMapping = Options.NotificationDataMappings var notifacationDataMapping = Options.NotificationDataMappings
.GetMapItemOrNull(publishProvider.Name, notification.CateGory); .GetMapItemOrNull(notification.Name, publishProvider.Name);
if (notifacationDataMapping != null) if (notifacationDataMapping != null)
{ {
notification.Data = notifacationDataMapping.MappingFunc(notification.Data); notification.Data = notifacationDataMapping.MappingFunc(notification.Data);

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

@ -3,8 +3,10 @@ using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Logging.Abstractions;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
using Volo.Abp.Threading;
namespace LINGYUN.Abp.Notifications namespace LINGYUN.Abp.Notifications
{ {
@ -39,11 +41,19 @@ namespace LINGYUN.Abp.Notifications
return reference; return reference;
} }
public ICancellationTokenProvider CancellationTokenProvider { get; set; }
protected NotificationPublishProvider(IServiceProvider serviceProvider) protected NotificationPublishProvider(IServiceProvider serviceProvider)
{ {
ServiceProvider = serviceProvider; ServiceProvider = serviceProvider;
CancellationTokenProvider = NullCancellationTokenProvider.Instance;
}
public async Task PublishAsync(NotificationInfo notification, IEnumerable<UserIdentifier> identifiers)
{
await PublishAsync(notification, identifiers, CancellationTokenProvider.Token);
} }
public abstract Task PublishAsync(NotificationInfo notification, IEnumerable<UserIdentifier> identifiers); protected abstract Task PublishAsync(NotificationInfo notification, IEnumerable<UserIdentifier> identifiers, CancellationToken cancellationToken = default);
} }
} }

123
aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NullNotificationStore.cs

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
@ -9,92 +10,178 @@ namespace LINGYUN.Abp.Notifications
[ExposeServices(typeof(INotificationStore))] [ExposeServices(typeof(INotificationStore))]
public class NullNotificationStore : INotificationStore public class NullNotificationStore : INotificationStore
{ {
public Task ChangeUserNotificationReadStateAsync(Guid? tenantId, Guid userId, long notificationId, NotificationReadState readState) public Task ChangeUserNotificationReadStateAsync(
Guid? tenantId,
Guid userId,
long notificationId,
NotificationReadState readState,
CancellationToken cancellationToken = default)
{ {
return Task.CompletedTask; return Task.CompletedTask;
} }
public Task DeleteAllUserSubscriptionAsync(Guid? tenantId, string notificationName) public Task DeleteAllUserSubscriptionAsync(
Guid? tenantId,
string notificationName,
CancellationToken cancellationToken = default)
{ {
return Task.CompletedTask; return Task.CompletedTask;
} }
public Task DeleteNotificationAsync(NotificationInfo notification) public Task DeleteNotificationAsync(
NotificationInfo notification,
CancellationToken cancellationToken = default)
{ {
return Task.CompletedTask; return Task.CompletedTask;
} }
public Task DeleteNotificationAsync(int batchCount) public Task DeleteNotificationAsync(
int batchCount,
CancellationToken cancellationToken = default)
{ {
return Task.CompletedTask; return Task.CompletedTask;
} }
public Task DeleteUserNotificationAsync(Guid? tenantId, Guid userId, long notificationId) public Task DeleteUserNotificationAsync(
Guid? tenantId,
Guid userId,
long notificationId,
CancellationToken cancellationToken = default)
{ {
return Task.CompletedTask; return Task.CompletedTask;
} }
public Task DeleteUserSubscriptionAsync(Guid? tenantId, Guid userId, string notificationName) public Task DeleteUserSubscriptionAsync(
Guid? tenantId,
Guid userId,
string notificationName,
CancellationToken cancellationToken = default)
{ {
return Task.CompletedTask; return Task.CompletedTask;
} }
public Task DeleteUserSubscriptionAsync(Guid? tenantId, IEnumerable<UserIdentifier> identifiers, string notificationName) public Task DeleteUserSubscriptionAsync(
Guid? tenantId,
IEnumerable<UserIdentifier> identifiers,
string notificationName,
CancellationToken cancellationToken = default)
{ {
return Task.CompletedTask; return Task.CompletedTask;
} }
public Task<NotificationInfo> GetNotificationOrNullAsync(Guid? tenantId, long notificationId) public Task<NotificationInfo> GetNotificationOrNullAsync(
Guid? tenantId,
long notificationId,
CancellationToken cancellationToken = default)
{ {
return Task.FromResult(new NotificationInfo()); return Task.FromResult(new NotificationInfo());
} }
public Task<List<NotificationSubscriptionInfo>> GetSubscriptionsAsync(Guid? tenantId, string notificationName) public Task<List<NotificationSubscriptionInfo>> GetUserSubscriptionsAsync(
Guid? tenantId,
string notificationName,
IEnumerable<UserIdentifier> identifiers,
CancellationToken cancellationToken = default)
{ {
return Task.FromResult(new List<NotificationSubscriptionInfo>()); return Task.FromResult(new List<NotificationSubscriptionInfo>());
} }
public Task<List<NotificationInfo>> GetUserNotificationsAsync(Guid? tenantId, Guid userId, NotificationReadState readState = NotificationReadState.UnRead, int maxResultCount = 10) public Task<List<NotificationInfo>> GetUserNotificationsAsync(
Guid? tenantId,
Guid userId,
NotificationReadState readState = NotificationReadState.UnRead,
int maxResultCount = 10,
CancellationToken cancellationToken = default)
{ {
return Task.FromResult(new List<NotificationInfo>()); return Task.FromResult(new List<NotificationInfo>());
} }
public Task<List<NotificationSubscriptionInfo>> GetUserSubscriptionsAsync(Guid? tenantId, Guid userId) public Task<int> GetUserNotificationsCountAsync(
Guid? tenantId,
Guid userId,
string filter = "",
NotificationReadState readState = NotificationReadState.UnRead,
CancellationToken cancellationToken = default)
{
return Task.FromResult(0);
}
public Task<List<NotificationInfo>> GetUserNotificationsAsync(
Guid? tenantId,
Guid userId,
string filter = "",
string sorting = nameof(NotificationInfo.CreationTime),
bool reverse = true,
NotificationReadState readState = NotificationReadState.UnRead,
int skipCount = 1,
int maxResultCount = 10,
CancellationToken cancellationToken = default)
{
return Task.FromResult(new List<NotificationInfo>());
}
public Task<List<NotificationSubscriptionInfo>> GetUserSubscriptionsAsync(
Guid? tenantId,
Guid userId,
CancellationToken cancellationToken = default)
{ {
return Task.FromResult(new List<NotificationSubscriptionInfo>()); return Task.FromResult(new List<NotificationSubscriptionInfo>());
} }
public Task<List<NotificationSubscriptionInfo>> GetUserSubscriptionsAsync(Guid? tenantId, string userName) public Task<List<NotificationSubscriptionInfo>> GetUserSubscriptionsAsync(
Guid? tenantId,
string userName,
CancellationToken cancellationToken = default)
{ {
return Task.FromResult(new List<NotificationSubscriptionInfo>()); return Task.FromResult(new List<NotificationSubscriptionInfo>());
} }
public Task InsertNotificationAsync(NotificationInfo notification) public Task InsertNotificationAsync(
NotificationInfo notification,
CancellationToken cancellationToken = default)
{ {
return Task.CompletedTask; return Task.CompletedTask;
} }
public Task InsertUserNotificationAsync(NotificationInfo notification, Guid userId) public Task InsertUserNotificationAsync(
NotificationInfo notification,
Guid userId,
CancellationToken cancellationToken = default)
{ {
return Task.CompletedTask; return Task.CompletedTask;
} }
public Task InsertUserNotificationsAsync(NotificationInfo notification, IEnumerable<Guid> userIds) public Task InsertUserNotificationsAsync(
NotificationInfo notification,
IEnumerable<Guid> userIds,
CancellationToken cancellationToken = default)
{ {
return Task.CompletedTask; return Task.CompletedTask;
} }
public Task InsertUserSubscriptionAsync(Guid? tenantId, UserIdentifier identifier, string notificationName) public Task InsertUserSubscriptionAsync(
Guid? tenantId,
UserIdentifier identifier,
string notificationName,
CancellationToken cancellationToken = default)
{ {
return Task.CompletedTask; return Task.CompletedTask;
} }
public Task InsertUserSubscriptionAsync(Guid? tenantId, IEnumerable<UserIdentifier> identifiers, string notificationName) public Task InsertUserSubscriptionAsync(
Guid? tenantId,
IEnumerable<UserIdentifier> identifiers,
string notificationName,
CancellationToken cancellationToken = default)
{ {
return Task.CompletedTask; return Task.CompletedTask;
} }
public Task<bool> IsSubscribedAsync(Guid? tenantId, Guid userId, string notificationName) public Task<bool> IsSubscribedAsync(
Guid? tenantId,
Guid userId,
string notificationName,
CancellationToken cancellationToken = default)
{ {
return Task.FromResult(false); return Task.FromResult(false);
} }

8
aspnet-core/modules/common/LINGYUN.Abp.RealTime.SignalR/Class1.cs

@ -1,8 +0,0 @@
using System;
namespace LINGYUN.Abp.RealTime.SignalR
{
public class Class1
{
}
}

1
aspnet-core/modules/common/LINGYUN.Abp.RealTime.SignalR/LINGYUN/Abp/RealTime/SignalR/AbpRealTimeSignalRModule.cs

@ -4,6 +4,7 @@ using Volo.Abp.Modularity;
namespace LINGYUN.Abp.RealTime.SignalR namespace LINGYUN.Abp.RealTime.SignalR
{ {
[DependsOn( [DependsOn(
typeof(AbpRealTimeModule),
typeof(AbpAspNetCoreSignalRModule))] typeof(AbpAspNetCoreSignalRModule))]
public class AbpRealTimeSignalRModule : AbpModule public class AbpRealTimeSignalRModule : AbpModule
{ {

86
aspnet-core/modules/common/LINGYUN.Abp.RealTime.SignalR/LINGYUN/Abp/RealTime/SignalR/Hubs/OnlineClientHubBase.cs

@ -1,80 +1,94 @@
using LINGYUN.Abp.RealTime.Client; using LINGYUN.Abp.RealTime.Client;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using System; using System;
using System.Threading.Tasks; using System.Threading.Tasks;
using Volo.Abp.AspNetCore.SignalR; using Volo.Abp.AspNetCore.SignalR;
using Volo.Abp.AspNetCore.WebClientInfo;
namespace LINGYUN.Abp.RealTime.SignalR namespace LINGYUN.Abp.RealTime.SignalR
{ {
public abstract class OnlineClientHubBase : AbpHub public abstract class OnlineClientHubBase : AbpHub, IClient
{ {
private IWebClientInfoProvider _webClientInfoProvider;
protected IWebClientInfoProvider WebClientInfoProvider => LazyGetRequiredService(ref _webClientInfoProvider);
private IOnlineClientManager _onlineClientManager; private IOnlineClientManager _onlineClientManager;
protected IOnlineClientManager OnlineClientManager => LazyGetRequiredService(ref _onlineClientManager); protected IOnlineClientManager OnlineClientManager => LazyGetRequiredService(ref _onlineClientManager);
private IHttpContextAccessor _httpContextAccessor;
protected IHttpContextAccessor HttpContextAccessor => LazyGetRequiredService(ref _httpContextAccessor);
public override async Task OnConnectedAsync() public override async Task OnConnectedAsync()
{ {
await base.OnConnectedAsync(); await base.OnConnectedAsync();
IOnlineClient onlineClient = CreateClientForCurrentConnection(); IOnlineClient onlineClient = CreateClientForCurrentConnection();
Logger.LogDebug("A client is connected: " + onlineClient.ToString()); await OnConnectedAsync(onlineClient);
OnlineClientManager.Add(onlineClient); }
await OnClientConnectedAsync(onlineClient);
public virtual async Task OnConnectedAsync(IOnlineClient client)
{
Logger.LogDebug("A client is connected: " + client.ToString());
OnlineClientManager.Add(client);
await OnClientConnectedAsync(client);
} }
public override async Task OnDisconnectedAsync(Exception exception) public override async Task OnDisconnectedAsync(Exception exception)
{ {
// 从通讯组移除
var onlineClient = OnlineClientManager.GetByConnectionIdOrNull(Context.ConnectionId);
await OnDisconnectedAsync(onlineClient);
await base.OnDisconnectedAsync(exception); await base.OnDisconnectedAsync(exception);
Logger.LogDebug("A client is disconnected: " + Context.ConnectionId); }
try
public virtual async Task OnDisconnectedAsync(IOnlineClient client)
{
if (client != null)
{ {
// 从通讯组移除 try
var onlineClient = OnlineClientManager.GetByConnectionIdOrNull(Context.ConnectionId);
if(onlineClient != null)
{ {
Logger.LogDebug("A client is disconnected: " + client);
// 移除在线客户端 // 移除在线客户端
OnlineClientManager.Remove(Context.ConnectionId); OnlineClientManager.Remove(Context.ConnectionId);
await OnClientDisconnectedAsync(onlineClient); await OnClientDisconnectedAsync(client);
}
catch (Exception ex)
{
Logger.LogWarning(ex.ToString(), ex);
} }
}
catch (Exception ex)
{
Logger.LogWarning(ex.ToString(), ex);
} }
} }
protected virtual IOnlineClient CreateClientForCurrentConnection() protected virtual IOnlineClient CreateClientForCurrentConnection()
{ {
return new OnlineClient(Context.ConnectionId, GetClientIpAddress(), return new OnlineClient(
CurrentTenant.Id, CurrentUser.Id) Context.ConnectionId,
WebClientInfoProvider.ClientIpAddress,
CurrentTenant.Id,
CurrentUser.Id)
{ {
ConnectTime = Clock.Now ConnectTime = Clock.Now,
UserName = CurrentUser.UserName,
UserAccount = CurrentUser.UserName,
Roles = CurrentUser.Roles ?? new string[0],
Properties = Context.Items
}; };
} }
protected virtual string GetClientIpAddress() protected virtual async Task OnClientConnectedAsync(IOnlineClient client)
{ {
try // 角色添加进组
{ foreach (var role in client.Roles)
return HttpContextAccessor.HttpContext?.Connection?.RemoteIpAddress?.ToString();
}
catch (Exception ex)
{ {
Logger.LogException(ex, LogLevel.Warning); await Groups.AddToGroupAsync(client.ConnectionId, role);
return null;
} }
} }
protected virtual Task OnClientConnectedAsync(IOnlineClient client) protected virtual async Task OnClientDisconnectedAsync(IOnlineClient client)
{ {
return Task.CompletedTask; // 角色添加进组
} foreach (var role in client.Roles)
{
protected virtual Task OnClientDisconnectedAsync(IOnlineClient client) await Groups.RemoveFromGroupAsync(client.ConnectionId, role);
{ }
return Task.CompletedTask;
} }
} }
} }

10
aspnet-core/modules/common/LINGYUN.Abp.RealTime/LINGYUN/Abp/RealTime/Client/IClient.cs

@ -0,0 +1,10 @@
using System.Threading.Tasks;
namespace LINGYUN.Abp.RealTime.Client
{
public interface IClient
{
Task OnConnectedAsync(IOnlineClient client);
Task OnDisconnectedAsync(IOnlineClient client);
}
}

6
aspnet-core/modules/common/LINGYUN.Abp.RealTime/LINGYUN/Abp/RealTime/Client/IOnlineClient.cs

@ -19,8 +19,10 @@ namespace LINGYUN.Abp.RealTime.Client
DateTime ConnectTime { get; } DateTime ConnectTime { get; }
object this[string key] { get; set; } string[] Roles { get; }
Dictionary<string, object> Properties { get; } object this[object key] { get; set; }
IDictionary<object, object> Properties { get; }
} }
} }

3
aspnet-core/modules/common/LINGYUN.Abp.RealTime/LINGYUN/Abp/RealTime/Client/IOnlineClientManager.cs

@ -1,6 +1,7 @@
using JetBrains.Annotations; using JetBrains.Annotations;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq.Expressions;
namespace LINGYUN.Abp.RealTime.Client namespace LINGYUN.Abp.RealTime.Client
{ {
@ -22,6 +23,8 @@ namespace LINGYUN.Abp.RealTime.Client
IReadOnlyList<IOnlineClient> GetAllClients(); IReadOnlyList<IOnlineClient> GetAllClients();
IReadOnlyList<IOnlineClient> GetAllClients(Expression<Func<IOnlineClient, bool>> predicate);
IReadOnlyList<IOnlineClient> GetAllByContext([NotNull] OnlineClientContext context); IReadOnlyList<IOnlineClient> GetAllByContext([NotNull] OnlineClientContext context);
} }
} }

6
aspnet-core/modules/common/LINGYUN.Abp.RealTime/LINGYUN/Abp/RealTime/Client/IOnlineClientStore.cs

@ -1,4 +1,6 @@
using System.Collections.Generic; using System;
using System.Collections.Generic;
using System.Linq.Expressions;
namespace LINGYUN.Abp.RealTime.Client namespace LINGYUN.Abp.RealTime.Client
{ {
@ -15,5 +17,7 @@ namespace LINGYUN.Abp.RealTime.Client
bool Contains(string connectionId); bool Contains(string connectionId);
IReadOnlyList<IOnlineClient> GetAll(); IReadOnlyList<IOnlineClient> GetAll();
IReadOnlyList<IOnlineClient> GetAll(Expression<Func<IOnlineClient, bool>> predicate);
} }
} }

12
aspnet-core/modules/common/LINGYUN.Abp.RealTime/LINGYUN/Abp/RealTime/Client/InMemoryOnlineClientStore.cs

@ -1,6 +1,9 @@
using System.Collections.Concurrent; using System;
using System.Collections.Concurrent;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Immutable; using System.Collections.Immutable;
using System.Linq;
using System.Linq.Expressions;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
namespace LINGYUN.Abp.RealTime.Client namespace LINGYUN.Abp.RealTime.Client
@ -43,5 +46,12 @@ namespace LINGYUN.Abp.RealTime.Client
{ {
return Clients.Values.ToImmutableList(); return Clients.Values.ToImmutableList();
} }
public IReadOnlyList<IOnlineClient> GetAll(Expression<Func<IOnlineClient, bool>> predicate)
{
return Clients.Values
.Where(predicate.Compile())
.ToImmutableList();
}
} }
} }

11
aspnet-core/modules/common/LINGYUN.Abp.RealTime/LINGYUN/Abp/RealTime/Client/OnlineClient.cs

@ -6,7 +6,7 @@ namespace LINGYUN.Abp.RealTime.Client
[Serializable] [Serializable]
public class OnlineClient : IOnlineClient public class OnlineClient : IOnlineClient
{ {
public object this[string key] public object this[object key]
{ {
get { return Properties[key]; } get { return Properties[key]; }
set { Properties[key] = value; } set { Properties[key] = value; }
@ -23,10 +23,12 @@ namespace LINGYUN.Abp.RealTime.Client
public string UserName { get; set; } public string UserName { get; set; }
public string[] Roles { get; set; }
public DateTime ConnectTime { get; set; } public DateTime ConnectTime { get; set; }
private Dictionary<string, object> _properties; private IDictionary<object, object> _properties;
public Dictionary<string, object> Properties public IDictionary<object, object> Properties
{ {
get { return _properties; } get { return _properties; }
set set
@ -53,7 +55,8 @@ namespace LINGYUN.Abp.RealTime.Client
TenantId = tenantId; TenantId = tenantId;
UserId = userId; UserId = userId;
Properties = new Dictionary<string, object>(); Roles = new string[0];
Properties = new Dictionary<object, object>();
} }
public override string ToString() public override string ToString()

11
aspnet-core/modules/common/LINGYUN.Abp.RealTime/LINGYUN/Abp/RealTime/Client/OnlineClientManager.cs

@ -3,6 +3,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Immutable; using System.Collections.Immutable;
using System.Linq; using System.Linq;
using System.Linq.Expressions;
using Volo.Abp; using Volo.Abp;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
@ -89,10 +90,12 @@ namespace LINGYUN.Abp.RealTime.Client
public virtual IReadOnlyList<IOnlineClient> GetAllClients() public virtual IReadOnlyList<IOnlineClient> GetAllClients()
{ {
lock (SyncObj) return Store.GetAll();
{ }
return Store.GetAll();
} public virtual IReadOnlyList<IOnlineClient> GetAllClients(Expression<Func<IOnlineClient, bool>> predicate)
{
return Store.GetAll(predicate);
} }
[NotNull] [NotNull]

4
aspnet-core/modules/common/LINGYUN.Abp.WeChat.Authorization/LINGYUN.Abp.WeChat.Authorization.csproj

@ -13,4 +13,8 @@
<PackageReference Include="Volo.Abp.Json" Version="3.2.0" /> <PackageReference Include="Volo.Abp.Json" Version="3.2.0" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\wechat\LINGYUN.Abp.WeChat\LINGYUN.Abp.WeChat.csproj" />
</ItemGroup>
</Project> </Project>

5
aspnet-core/modules/common/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/AbpWeChatAuthorizationModule.cs

@ -7,7 +7,10 @@ using Volo.Abp.Modularity;
namespace LINGYUN.Abp.WeChat.Authorization namespace LINGYUN.Abp.WeChat.Authorization
{ {
[DependsOn(typeof(AbpJsonModule), typeof(AbpCachingModule))] [DependsOn(
typeof(AbpWeChatModule),
typeof(AbpJsonModule),
typeof(AbpCachingModule))]
public class AbpWeChatAuthorizationModule : AbpModule public class AbpWeChatAuthorizationModule : AbpModule
{ {
public override void ConfigureServices(ServiceConfigurationContext context) public override void ConfigureServices(ServiceConfigurationContext context)

12
aspnet-core/modules/common/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/OpenId/IUserWeChatCodeFinder.cs

@ -0,0 +1,12 @@
using System;
using System.Threading.Tasks;
namespace LINGYUN.Abp.WeChat.Authorization
{
public interface IUserWeChatCodeFinder
{
Task<string> FindByUserIdAsync(Guid userId);
Task<string> FindByUserNameAsync(string userName);
}
}

7
aspnet-core/modules/common/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/OpenId/IWeChatOpenIdFinder.cs

@ -1,9 +1,14 @@
using System.Threading.Tasks; using System;
using System.Threading.Tasks;
namespace LINGYUN.Abp.WeChat.Authorization namespace LINGYUN.Abp.WeChat.Authorization
{ {
public interface IWeChatOpenIdFinder public interface IWeChatOpenIdFinder
{ {
Task<WeChatOpenId> FindAsync(string code); Task<WeChatOpenId> FindAsync(string code);
Task<WeChatOpenId> FindByUserIdAsync(Guid userId);
Task<WeChatOpenId> FindByUserNameAsync(string userName);
} }
} }

19
aspnet-core/modules/common/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/OpenId/NullUserWeChatCodeFinder.cs

@ -0,0 +1,19 @@
using System;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
namespace LINGYUN.Abp.WeChat.Authorization
{
public class NullUserWeChatCodeFinder : IUserWeChatCodeFinder, ISingletonDependency
{
public Task<string> FindByUserIdAsync(Guid userId)
{
return Task.FromResult(userId.ToString());
}
public Task<string> FindByUserNameAsync(string userName)
{
return Task.FromResult(userName);
}
}
}

6
aspnet-core/modules/common/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/OpenId/WeChatOpenIdCacheItem.cs

@ -18,11 +18,9 @@ namespace LINGYUN.Abp.WeChat.Authorization
WeChatOpenId = weChatOpenId; WeChatOpenId = weChatOpenId;
} }
public static string CalculateCacheKey(string code, Guid? tenantId = null) public static string CalculateCacheKey(string code)
{ {
string tenant = tenantId != null ? tenantId.Value.ToString("D") : "host"; return "c:" + code;
return "t:" + tenant + ",c:" + code;
} }
} }
} }

27
aspnet-core/modules/common/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/OpenId/WeChatOpenIdFinder.cs

@ -22,16 +22,19 @@ namespace LINGYUN.Abp.WeChat.Authorization
protected ICurrentTenant CurrentTenant { get; } protected ICurrentTenant CurrentTenant { get; }
protected IHttpClientFactory HttpClientFactory { get; } protected IHttpClientFactory HttpClientFactory { get; }
protected IJsonSerializer JsonSerializer { get; } protected IJsonSerializer JsonSerializer { get; }
protected IUserWeChatCodeFinder UserWeChatCodeFinder { get; }
protected IDistributedCache<WeChatOpenIdCacheItem> Cache { get; } protected IDistributedCache<WeChatOpenIdCacheItem> Cache { get; }
public WeChatOpenIdFinder( public WeChatOpenIdFinder(
ICurrentTenant currentTenant, ICurrentTenant currentTenant,
IJsonSerializer jsonSerializer, IJsonSerializer jsonSerializer,
IUserWeChatCodeFinder userWeChatCodeFinder,
IHttpClientFactory httpClientFactory, IHttpClientFactory httpClientFactory,
IOptions<AbpWeChatOptions> options, IOptions<AbpWeChatOptions> options,
IDistributedCache<WeChatOpenIdCacheItem> cache) IDistributedCache<WeChatOpenIdCacheItem> cache)
{ {
CurrentTenant = currentTenant; CurrentTenant = currentTenant;
JsonSerializer = jsonSerializer; JsonSerializer = jsonSerializer;
UserWeChatCodeFinder = userWeChatCodeFinder;
HttpClientFactory = httpClientFactory; HttpClientFactory = httpClientFactory;
Cache = cache; Cache = cache;
@ -43,12 +46,30 @@ namespace LINGYUN.Abp.WeChat.Authorization
{ {
// TODO: 如果需要获取SessionKey的话呢,需要再以openid作为标识来缓存一下吗 // TODO: 如果需要获取SessionKey的话呢,需要再以openid作为标识来缓存一下吗
// 或者前端保存code,通过传递code来获取 // 或者前端保存code,通过传递code来获取
return (await GetCacheItemAsync(code, CurrentTenant.Id)).WeChatOpenId; return (await GetCacheItemAsync(code)).WeChatOpenId;
} }
protected virtual async Task<WeChatOpenIdCacheItem> GetCacheItemAsync(string code, Guid? tenantId = null) public virtual async Task<WeChatOpenId> FindByUserIdAsync(Guid userId)
{ {
var cacheKey = WeChatOpenIdCacheItem.CalculateCacheKey(code, tenantId); var code = await UserWeChatCodeFinder.FindByUserIdAsync(userId);
// TODO: 如果需要获取SessionKey的话呢,需要再以openid作为标识来缓存一下吗
// 或者前端保存code,通过传递code来获取
return (await GetCacheItemAsync(code)).WeChatOpenId;
}
public virtual async Task<WeChatOpenId> FindByUserNameAsync(string userName)
{
var code = await UserWeChatCodeFinder.FindByUserNameAsync(userName);
// TODO: 如果需要获取SessionKey的话呢,需要再以openid作为标识来缓存一下吗
// 或者前端保存code,通过传递code来获取
return (await GetCacheItemAsync(code)).WeChatOpenId;
}
protected virtual async Task<WeChatOpenIdCacheItem> GetCacheItemAsync(string code)
{
var cacheKey = WeChatOpenIdCacheItem.CalculateCacheKey(code);
Logger.LogDebug($"WeChatOpenIdFinder.GetCacheItemAsync: {cacheKey}"); Logger.LogDebug($"WeChatOpenIdFinder.GetCacheItemAsync: {cacheKey}");

5
aspnet-core/modules/common/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/Token/IWeChatTokenProvider.cs

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

13
aspnet-core/modules/common/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/Token/WeChatTokenProvider.cs

@ -4,6 +4,7 @@ using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using System; using System;
using System.Net.Http; using System.Net.Http;
using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Volo.Abp.Caching; using Volo.Abp.Caching;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
@ -33,18 +34,18 @@ namespace LINGYUN.Abp.WeChat.Authorization
Logger = NullLogger<WeChatTokenProvider>.Instance; Logger = NullLogger<WeChatTokenProvider>.Instance;
} }
public virtual async Task<WeChatToken> GetTokenAsync() public virtual async Task<WeChatToken> GetTokenAsync(CancellationToken cancellationToken = default)
{ {
return (await GetCacheItemAsync("WeChatToken", Options.AppId)).WeChatToken; return (await GetCacheItemAsync("WeChatToken", Options.AppId, cancellationToken)).WeChatToken;
} }
protected virtual async Task<WeChatTokenCacheItem> GetCacheItemAsync(string provider, string appId) protected virtual async Task<WeChatTokenCacheItem> GetCacheItemAsync(string provider, string appId, CancellationToken cancellationToken = default)
{ {
var cacheKey = WeChatTokenCacheItem.CalculateCacheKey(provider, appId); var cacheKey = WeChatTokenCacheItem.CalculateCacheKey(provider, appId);
Logger.LogDebug($"WeChatTokenProvider.GetCacheItemAsync: {cacheKey}"); Logger.LogDebug($"WeChatTokenProvider.GetCacheItemAsync: {cacheKey}");
var cacheItem = await Cache.GetAsync(cacheKey); var cacheItem = await Cache.GetAsync(cacheKey, token: cancellationToken);
if (cacheItem != null) if (cacheItem != null)
{ {
@ -64,7 +65,7 @@ namespace LINGYUN.Abp.WeChat.Authorization
GrantType = "client_credential" GrantType = "client_credential"
}; };
var response = await client.RequestWeChatCodeTokenAsync(request); var response = await client.RequestWeChatCodeTokenAsync(request, cancellationToken);
var responseContent = await response.Content.ReadAsStringAsync(); var responseContent = await response.Content.ReadAsStringAsync();
var weChatTokenResponse = JsonSerializer.Deserialize<WeChatTokenResponse>(responseContent); var weChatTokenResponse = JsonSerializer.Deserialize<WeChatTokenResponse>(responseContent);
var weChatToken = weChatTokenResponse.ToWeChatToken(); var weChatToken = weChatTokenResponse.ToWeChatToken();
@ -78,7 +79,7 @@ namespace LINGYUN.Abp.WeChat.Authorization
AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(weChatToken.ExpiresIn - 120) AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(weChatToken.ExpiresIn - 120)
}; };
await Cache.SetAsync(cacheKey, cacheItem, cacheOptions); await Cache.SetAsync(cacheKey, cacheItem, cacheOptions, token: cancellationToken);
Logger.LogDebug($"Finished setting the cache item: {cacheKey}"); Logger.LogDebug($"Finished setting the cache item: {cacheKey}");

22
aspnet-core/modules/common/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/WeChatAuthorizationConsts.cs

@ -0,0 +1,22 @@
namespace LINGYUN.Abp.WeChat.Authorization
{
public class WeChatAuthorizationConsts
{
/// <summary>
/// 微信提供者标识
/// </summary>
public static string ProviderKey { get; set; } = "WeChat";
/// <summary>
/// 微信Code参数名称
/// </summary>
public static string WeCahtCodeKey { get; set; } = "wx-code";
/// <summary>
/// 微信OpenId参数名称
/// </summary>
public static string WeCahtOpenIdKey { get; set; } = "wx-open-id";
/// <summary>
/// 微信SessionKey参数名称
/// </summary>
public static string WeCahtSessionKey { get; set; } = "wx-session-key";
}
}

1
aspnet-core/modules/identity/LINGYUN.Abp.Identity.Application.Contracts/LINGYUN/Abp/Identity/IIdentityUserAppService.cs

@ -16,7 +16,6 @@ namespace LINGYUN.Abp.Identity
Task RemoveOrganizationUnitsAsync(Guid id, Guid ouId); Task RemoveOrganizationUnitsAsync(Guid id, Guid ouId);
#endregion #endregion
#region ClaimType #region ClaimType

8
aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN/Abp/IdentityServer/WeChatValidator/WeChatTokenGrantValidator.cs

@ -72,6 +72,7 @@ namespace LINGYUN.Abp.IdentityServer.WeChatValidator
Localizer["InvalidGrant:GrantTypeInvalid"]); Localizer["InvalidGrant:GrantTypeInvalid"]);
return; return;
} }
// TODO: 统一命名规范, 微信认证传递的 code 改为 WeChatOpenIdConsts.WeCahtCodeKey
var wechatCode = raw.Get(WeChatValidatorConsts.WeChatValidatorTokenName); var wechatCode = raw.Get(WeChatValidatorConsts.WeChatValidatorTokenName);
if (wechatCode.IsNullOrWhiteSpace() || wechatCode.IsNullOrWhiteSpace()) if (wechatCode.IsNullOrWhiteSpace() || wechatCode.IsNullOrWhiteSpace())
{ {
@ -81,7 +82,7 @@ namespace LINGYUN.Abp.IdentityServer.WeChatValidator
return; return;
} }
var wechatOpenId = await WeChatOpenIdFinder.FindAsync(wechatCode); var wechatOpenId = await WeChatOpenIdFinder.FindAsync(wechatCode);
var currentUser = await UserManager.FindByLoginAsync("WeChat", wechatOpenId.OpenId); var currentUser = await UserManager.FindByLoginAsync(WeChatAuthorizationConsts.ProviderKey, wechatOpenId.OpenId);
if(currentUser == null) if(currentUser == null)
{ {
Logger.LogWarning("Invalid grant type: wechat openid: {0} not register", wechatOpenId.OpenId); Logger.LogWarning("Invalid grant type: wechat openid: {0} not register", wechatOpenId.OpenId);
@ -91,6 +92,11 @@ namespace LINGYUN.Abp.IdentityServer.WeChatValidator
} }
var sub = await UserManager.GetUserIdAsync(currentUser); var sub = await UserManager.GetUserIdAsync(currentUser);
// 微信登录的用户写入token
currentUser.SetToken(WeChatAuthorizationConsts.ProviderKey, WeChatAuthorizationConsts.WeCahtCodeKey, wechatCode);
currentUser.SetToken(WeChatAuthorizationConsts.ProviderKey, WeChatAuthorizationConsts.WeCahtOpenIdKey, wechatOpenId.OpenId);
currentUser.SetToken(WeChatAuthorizationConsts.ProviderKey, WeChatAuthorizationConsts.WeCahtSessionKey, wechatOpenId.SessionKey);
var additionalClaims = new List<Claim>(); var additionalClaims = new List<Claim>();
if (currentUser.TenantId.HasValue) if (currentUser.TenantId.HasValue)
{ {

40
aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChatValidator/LINGYUN/Abp/WeChat/Authorization/UserWeChatCodeFinder.cs

@ -0,0 +1,40 @@
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Identity;
namespace LINGYUN.Abp.WeChat.Authorization
{
// TODO: 真正的项目需要扩展Abp框架实体来关联微信
[Dependency(ServiceLifetime.Transient, ReplaceServices = true)]
[ExposeServices(typeof(IUserWeChatCodeFinder))]
public class UserWeChatCodeFinder : IUserWeChatCodeFinder
{
protected IdentityUserManager UserManager { get; }
public UserWeChatCodeFinder(
IdentityUserManager userManager)
{
UserManager = userManager;
}
public virtual async Task<string> FindByUserIdAsync(Guid userId)
{
var user = await UserManager.FindByIdAsync(userId.ToString());
var weChatCodeToken = user?.FindToken(WeChatAuthorizationConsts.ProviderKey, WeChatAuthorizationConsts.WeCahtCodeKey);
return weChatCodeToken?.Value ?? userId.ToString();
}
public virtual async Task<string> FindByUserNameAsync(string userName)
{
var user = await UserManager.FindByNameAsync(userName);
var weChatCodeToken = user?.FindToken(WeChatAuthorizationConsts.ProviderKey, WeChatAuthorizationConsts.WeCahtCodeKey);
return weChatCodeToken?.Value ?? userName;
}
}
}

7
aspnet-core/modules/message/LINGYUN.Abp.MessageService.Application.Contracts/LINGYUN/Abp/MessageService/Chat/Dto/MyFriendAddRequestDto.cs

@ -0,0 +1,7 @@
namespace LINGYUN.Abp.MessageService.Chat
{
public class MyFriendAddRequestDto : MyFriendOperationDto
{
public string RemarkName { get; set; }
}
}

1
aspnet-core/modules/message/LINGYUN.Abp.MessageService.Application.Contracts/LINGYUN/Abp/MessageService/Chat/Dto/MyFriendCreateDto.cs

@ -2,6 +2,5 @@
{ {
public class MyFriendCreateDto : MyFriendOperationDto public class MyFriendCreateDto : MyFriendOperationDto
{ {
public string RemarkName { get; set; }
} }
} }

2
aspnet-core/modules/message/LINGYUN.Abp.MessageService.Application.Contracts/LINGYUN/Abp/MessageService/Chat/IMyFriendAppService.cs

@ -14,5 +14,7 @@ namespace LINGYUN.Abp.MessageService.Chat
Task CreateAsync(MyFriendCreateDto input); Task CreateAsync(MyFriendCreateDto input);
Task DeleteAsync(MyFriendOperationDto input); Task DeleteAsync(MyFriendOperationDto input);
Task AddRequestAsync(MyFriendAddRequestDto input);
} }
} }

4
aspnet-core/modules/message/LINGYUN.Abp.MessageService.Application.Contracts/LINGYUN/Abp/MessageService/Localization/ApplicationContracts/en.json

@ -3,6 +3,8 @@
"texts": { "texts": {
"Permission:MessageService": "Message service", "Permission:MessageService": "Message service",
"Permission:Notification": "Notification", "Permission:Notification": "Notification",
"Permission:Delete": "Delete" "Permission:Delete": "Delete",
"Permission:Hangfire": "Hangfire dashboard",
"Permission:ManageQueue": "Manage queue"
} }
} }

4
aspnet-core/modules/message/LINGYUN.Abp.MessageService.Application.Contracts/LINGYUN/Abp/MessageService/Localization/ApplicationContracts/zh-Hans.json

@ -3,6 +3,8 @@
"texts": { "texts": {
"Permission:MessageService": "消息服务", "Permission:MessageService": "消息服务",
"Permission:Notification": "通知管理", "Permission:Notification": "通知管理",
"Permission:Delete": "删除" "Permission:Delete": "删除",
"Permission:Hangfire": "Hangfire仪表板",
"Permission:ManageQueue": "管理队列"
} }
} }

28
aspnet-core/modules/message/LINGYUN.Abp.MessageService.Application.Contracts/LINGYUN/Abp/MessageService/Notifications/Dto/NotificationDto.cs

@ -0,0 +1,28 @@
using LINGYUN.Abp.Notifications;
namespace LINGYUN.Abp.MessageService.Notifications
{
public class NotificationDto
{
/// <summary>
/// 通知名称
/// </summary>
public string Name { get; set; }
/// <summary>
/// 显示名称
/// </summary>
public string DisplayName { get; set; }
/// <summary>
/// 说明
/// </summary>
public string Description { get; set; }
/// <summary>
/// 存活类型
/// </summary>
public NotificationLifetime Lifetime { get; set; }
/// <summary>
/// 通知类型
/// </summary>
public NotificationType Type { get; set; }
}
}

11
aspnet-core/modules/message/LINGYUN.Abp.MessageService.Application.Contracts/LINGYUN/Abp/MessageService/Notifications/Dto/NotificationGroupDto.cs

@ -0,0 +1,11 @@
using System.Collections.Generic;
namespace LINGYUN.Abp.MessageService.Notifications
{
public class NotificationGroupDto
{
public string Name { get; set; }
public string DisplayName { get; set; }
public List<NotificationDto> Notifications { get; set; } = new List<NotificationDto>();
}
}

22
aspnet-core/modules/message/LINGYUN.Abp.MessageService.Application.Contracts/LINGYUN/Abp/MessageService/Notifications/Dto/NotificationSendDto.cs

@ -0,0 +1,22 @@
using LINGYUN.Abp.Notifications;
using System;
using System.ComponentModel.DataAnnotations;
namespace LINGYUN.Abp.MessageService.Notifications
{
public class NotificationSendDto
{
[Required]
[StringLength(NotificationConsts.MaxNameLength)]
public string Name { get; set; }
public NotificationData Data { get; set; } = new NotificationData();
public Guid? ToUserId { get; set; }
[StringLength(128)]
public string ToUserName { get; set; }
public NotificationSeverity Severity { get; set; } = NotificationSeverity.Info;
}
}

2
aspnet-core/modules/message/LINGYUN.Abp.MessageService.Application.Contracts/LINGYUN/Abp/MessageService/Notifications/Dto/UserNotificationGetByPagedDto.cs

@ -7,6 +7,8 @@ namespace LINGYUN.Abp.MessageService.Notifications
{ {
public string Filter { get; set; } public string Filter { get; set; }
public bool Reverse { get; set; }
public NotificationReadState ReadState { get; set; } = NotificationReadState.Read; public NotificationReadState ReadState { get; set; } = NotificationReadState.Read;
} }
} }

21
aspnet-core/modules/message/LINGYUN.Abp.MessageService.Application.Contracts/LINGYUN/Abp/MessageService/Notifications/IMyNotificationAppService.cs

@ -0,0 +1,21 @@
using LINGYUN.Abp.Notifications;
using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
namespace LINGYUN.Abp.MessageService.Notifications
{
public interface IMyNotificationAppService :
IReadOnlyAppService<
NotificationInfo,
long,
UserNotificationGetByPagedDto
>,
IDeleteAppService<long>
{
Task SendNofiterAsync(NotificationSendDto input);
Task<ListResultDto<NotificationGroupDto>> GetAssignableNotifiersAsync();
}
}

41
aspnet-core/modules/message/LINGYUN.Abp.MessageService.Application.Contracts/LINGYUN/Abp/MessageService/Notifications/INotificationAppService.cs

@ -1,41 +0,0 @@
using LINGYUN.Abp.Notifications;
using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
namespace LINGYUN.Abp.MessageService.Notifications
{
public interface INotificationAppService : IApplicationService
{
/// <summary>
/// 查询通知明细
/// </summary>
/// <param name="notificationGetById"></param>
/// <returns></returns>
Task<NotificationInfo> GetAsync(NotificationGetByIdDto notificationGetById);
/// <summary>
/// 删除通知
/// </summary>
/// <param name="notificationGetById"></param>
/// <returns></returns>
Task DeleteAsync(NotificationGetByIdDto notificationGetById);
/// <summary>
/// 删除用户通知
/// </summary>
/// <param name="notificationGetById"></param>
/// <returns></returns>
Task DeleteUserNotificationAsync(NotificationGetByIdDto notificationGetById);
/// <summary>
/// 变更通知阅读状态
/// </summary>
/// <param name="userNotificationChangeRead"></param>
/// <returns></returns>
Task ChangeUserNotificationReadStateAsync(UserNotificationChangeReadStateDto userNotificationChangeRead);
/// <summary>
/// 获取用户通知列表
/// </summary>
/// <param name="userNotificationGetByPaged"></param>
/// <returns></returns>
Task<PagedResultDto<NotificationInfo>> GetUserNotificationsAsync(UserNotificationGetByPagedDto userNotificationGetByPaged);
}
}

7
aspnet-core/modules/message/LINGYUN.Abp.MessageService.Application.Contracts/LINGYUN/Abp/MessageService/Permissions/MessageServicePermissions.cs

@ -10,5 +10,12 @@
public const string Delete = Default + ".Delete"; public const string Delete = Default + ".Delete";
} }
public class Hangfire
{
public const string Default = GroupName + ".Hangfire";
public const string ManageQueue = Default + ".ManageQueue";
}
} }
} }

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save