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
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
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
Global
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}.Release|Any CPU.ActiveCfg = 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
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -736,8 +750,8 @@ Global
{0D1DB712-B48D-4FB7-9A47-694C668A62E3} = {608A3BD0-FC8D-48B0-B1C5-F3203A3BE99F}
{9E12ADBF-713B-4FE7-B71F-52B5078A57CE} = {3CDBA2A6-DC8A-48C5-8A6C-AF207394B43D}
{02043AD5-5E06-4EDD-8162-983E766C38EC} = {0439B173-F41E-4CE0-A44A-CCB70328F272}
{85EF4251-EFC4-4CC9-912B-EA5DB1E2E359} = {8AC72641-30D3-4ACF-89FA-808FADC55C2E}
{263A8A1C-69D0-4C3F-B33E-8F0831C146EB} = {8AC72641-30D3-4ACF-89FA-808FADC55C2E}
{85EF4251-EFC4-4CC9-912B-EA5DB1E2E359} = {DD9BE9E7-F6BF-4869-BCD2-82F5072BDA21}
{263A8A1C-69D0-4C3F-B33E-8F0831C146EB} = {DD9BE9E7-F6BF-4869-BCD2-82F5072BDA21}
{47CC8F7A-681D-42B9-AE04-78453782C1B6} = {8AC72641-30D3-4ACF-89FA-808FADC55C2E}
{F595CB9F-B117-4D62-A1AE-48599927DB36} = {8AC72641-30D3-4ACF-89FA-808FADC55C2E}
{5CF403B2-47C9-4E4E-8856-0294BDD64884} = {8AC72641-30D3-4ACF-89FA-808FADC55C2E}
@ -805,6 +819,9 @@ Global
{5F43141B-6C63-4547-B9D6-D69EC3D7CA7E} = {9E72FEB9-A626-4312-892B-CDD043879758}
{A66D48C9-F141-4111-9169-CEB64AFFF61D} = {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
GlobalSection(ExtensibilityGlobals) = postSolution
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
File Encoding : 65001
Date: 23/10/2020 19:13:56
Date: 31/10/2020 11:28:59
*/
SET NAMES utf8mb4;
@ -54,7 +54,7 @@ CREATE TABLE `appapigatewayaggregate` (
`Priority` int(0) NULL DEFAULT NULL,
`UpstreamHttpMethod` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
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
@ -76,7 +76,7 @@ CREATE TABLE `appapigatewayaggregateconfig` (
PRIMARY KEY (`Id`) 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
) 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
@ -90,7 +90,7 @@ CREATE TABLE `appapigatewayauthoptions` (
PRIMARY KEY (`Id`) 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
) 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
@ -205,6 +205,11 @@ INSERT INTO `appapigatewayauthoptions` VALUES (141, 1319554948434595840, '', '')
INSERT INTO `appapigatewayauthoptions` VALUES (142, 1319555067183730688, '', '');
INSERT INTO `appapigatewayauthoptions` VALUES (143, 1319555230765780992, '', '');
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
@ -222,7 +227,7 @@ CREATE TABLE `appapigatewaybalanceroptions` (
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_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
@ -338,6 +343,11 @@ INSERT INTO `appapigatewaybalanceroptions` VALUES (144, NULL, 131955494843459584
INSERT INTO `appapigatewaybalanceroptions` VALUES (145, NULL, 1319555067183730688, '', '', 0);
INSERT INTO `appapigatewaybalanceroptions` VALUES (146, NULL, 1319555230765780992, '', '', 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
@ -351,7 +361,7 @@ CREATE TABLE `appapigatewaycacheoptions` (
PRIMARY KEY (`Id`) 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
) 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
@ -466,6 +476,11 @@ INSERT INTO `appapigatewaycacheoptions` VALUES (141, 1319554948434595840, 0, '')
INSERT INTO `appapigatewaycacheoptions` VALUES (142, 1319555067183730688, 0, '');
INSERT INTO `appapigatewaycacheoptions` VALUES (143, 1319555230765780992, 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
@ -485,7 +500,7 @@ CREATE TABLE `appapigatewaydiscovery` (
PRIMARY KEY (`Id`) 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
) 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
@ -506,7 +521,7 @@ CREATE TABLE `appapigatewaydynamicreroute` (
`AppId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
PRIMARY KEY (`Id`) 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
@ -526,7 +541,7 @@ CREATE TABLE `appapigatewayglobalconfiguration` (
`AppId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
PRIMARY KEY (`Id`) 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
@ -543,7 +558,7 @@ CREATE TABLE `appapigatewayheaders` (
`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,
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
@ -555,7 +570,7 @@ CREATE TABLE `appapigatewayhostandport` (
`Host` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
`Port` int(0) NULL DEFAULT 0,
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
@ -575,7 +590,7 @@ CREATE TABLE `appapigatewayhttpoptions` (
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_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
@ -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 (146, NULL, 1319555230765780992, 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
@ -708,7 +728,7 @@ CREATE TABLE `appapigatewayqosoptions` (
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_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
@ -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 (146, NULL, 1319555230765780992, 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
@ -840,7 +865,7 @@ CREATE TABLE `appapigatewayratelimitoptions` (
PRIMARY KEY (`Id`) 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
) 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
@ -865,7 +890,7 @@ CREATE TABLE `appapigatewayratelimitrule` (
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_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
@ -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 (143, 1319555230765780992, 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
@ -1019,7 +1049,7 @@ CREATE TABLE `appapigatewayreroute` (
PRIMARY KEY (`Id`) USING BTREE,
UNIQUE INDEX `AK_AppApiGatewayReRoute_ReRouteId`(`ReRouteId`) 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
@ -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 (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 (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 (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 (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, '{}', '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 (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');
@ -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 (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 (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
@ -1177,7 +1212,7 @@ CREATE TABLE `appapigatewaysecurityoptions` (
PRIMARY KEY (`Id`) 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
) 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
@ -1292,6 +1327,11 @@ INSERT INTO `appapigatewaysecurityoptions` VALUES (141, 1319554948434595840, '',
INSERT INTO `appapigatewaysecurityoptions` VALUES (142, 1319555067183730688, '', '');
INSERT INTO `appapigatewaysecurityoptions` VALUES (143, 1319555230765780992, '', '');
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
@ -1313,25 +1353,7 @@ CREATE TABLE `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 (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');
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');
-- ----------------------------
-- 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 />
</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>
<ProjectReference Include="..\LINGYUN.Abp.ExceptionHandling\LINGYUN.Abp.ExceptionHandling.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
{
@ -6,7 +8,23 @@ namespace LINGYUN.Abp.ExceptionHandling.Notifications
{
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 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.VirtualFileSystem;
namespace LINGYUN.Abp.ExceptionHandling.Notifications
{
@ -8,5 +11,19 @@ namespace LINGYUN.Abp.ExceptionHandling.Notifications
typeof(AbpNotificationModule))]
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)
{
var notificationDispatcher = context.ServiceProvider.GetRequiredService<INotificationDispatcher>();
var notificationName = NotificationNameNormalizer
.NormalizerName(AbpExceptionHandlingNotificationNames.NotificationName);
NotificationData notificationData;
if (CurrentTenant.IsAvailable)
{
notificationData = NotificationData.CreateTenantNotificationData(CurrentTenant.Id.Value);
}
else
{
notificationData = NotificationData.CreateNotificationData();
}
var notificationSender = context.ServiceProvider.GetRequiredService<INotificationSender>();
NotificationData notificationData = new NotificationData();
// 写入通知数据
//TODO:集成TextTemplate完成格式化的推送
notificationData.WriteStandardData(
context.Exception.GetType().FullName, context.Exception.Message,
DateTime.Now, "System");
context.Exception.GetType().FullName,
context.Exception.Message,
DateTime.Now,
"System");
await notificationDispatcher.DispatchAsync(notificationName, notificationData,
CurrentTenant.Id, NotificationSeverity.Error);
await notificationSender.SendNofiterAsync(
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>
<ItemGroup>
<PackageReference Include="Volo.Abp.Core" Version="3.2.0" />
<PackageReference Include="Volo.Abp.Localization" Version="3.2.0" />
</ItemGroup>
</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
{
[DependsOn(typeof(AbpLocalizationModule))]
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.IM.SignalR.Messages;
using LINGYUN.Abp.RealTime.SignalR;
using Volo.Abp.AspNetCore.SignalR;
using Volo.Abp.Modularity;
namespace LINGYUN.Abp.IM.SignalR
{
[DependsOn(
typeof(AbpIMModule),
typeof(AbpRealTimeSignalRModule),
typeof(AbpAspNetCoreSignalRModule),
typeof(AbpAspNetCoreSignalRJwtTokenModule))]
public class AbpIMSignalRModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<AbpIMOptions>(options =>
{
options.Providers.Add<SignalRMessageSenderProvider>();
});
Configure<AbpAspNetCoreSignalRJwtTokenMapPathOptions>(options =>
{
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.Linq;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Users;
@ -35,6 +34,7 @@ namespace LINGYUN.Abp.IM.SignalR.Hubs
protected override async Task OnClientConnectedAsync(IOnlineClient client)
{
await base.OnClientConnectedAsync(client);
// 加入通讯组
var userGroups = await UserGroupStore.GetUserGroupsAsync(client.TenantId, client.UserId.Value);
foreach (var group in userGroups)
@ -61,33 +61,35 @@ namespace LINGYUN.Abp.IM.SignalR.Hubs
}
}
protected override async Task OnClientDisconnectedAsync(IOnlineClient client)
{
// 从通讯组断开会话
var userGroups = await UserGroupStore.GetUserGroupsAsync(client.TenantId, client.UserId.Value);
foreach (var group in userGroups)
{
await Groups.RemoveFromGroupAsync(client.ConnectionId, group.Name);
var groupClient = Clients.Group(group.Name);
if (groupClient != null)
{
// 发送用户下线指令
await groupClient.SendAsync("onUserOfflined", client.TenantId, client.UserId.Value);
}
}
// 发送好友下线通知
var userFriends = await FriendStore.GetListAsync(client.TenantId, client.UserId.Value);
if (userFriends.Count > 0)
{
var friendClientIds = userFriends.Select(friend => friend.FriendId.ToString()).ToImmutableArray();
var userClients = Clients.Users(friendClientIds);
if (userClients != null)
{
await userClients.SendAsync("onUserOfflined", client.TenantId, client.UserId.Value);
}
}
}
//protected override async Task OnClientDisconnectedAsync(IOnlineClient client)
//{
// // 从通讯组断开会话
// var userGroups = await UserGroupStore.GetUserGroupsAsync(client.TenantId, client.UserId.Value, Context.ConnectionAborted);
// foreach (var group in userGroups)
// {
// await Groups.RemoveFromGroupAsync(client.ConnectionId, group.Name, Context.ConnectionAborted);
// var groupClient = Clients.Group(group.Name);
// if (groupClient != null)
// {
// // 发送用户下线指令
// await groupClient.SendAsync("onUserOfflined", client.TenantId, client.UserId.Value, Context.ConnectionAborted);
// }
// }
// // 发送好友下线通知
// var userFriends = await FriendStore.GetListAsync(client.TenantId, client.UserId.Value, cancellationToken: Context.ConnectionAborted);
// if (userFriends.Count > 0)
// {
// var friendClientIds = userFriends.Select(friend => friend.FriendId.ToString()).ToImmutableArray();
// var userClients = Clients.Users(friendClientIds);
// if (userClients != null)
// {
// await userClients.SendAsync("onUserOfflined", client.TenantId, client.UserId.Value, Context.ConnectionAborted);
// }
// }
// await base.OnClientDisconnectedAsync(client);
//}
[HubMethodName("LastContactFriends")]
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 lastContractFriends = await FriendStore
.GetLastContactListAsync(tenantId, userId, skipCount, maxResultCount);
.GetLastContactListAsync(tenantId, userId, skipCount, maxResultCount, cancellationToken: Context.ConnectionAborted);
return new PagedResultDto<UserFriend>(myFrientCount, lastContractFriends);
}
@ -123,7 +125,7 @@ namespace LINGYUN.Abp.IM.SignalR.Hubs
{
var messages = await MessageStore
.GetLastChatMessagesAsync(
CurrentTenant.Id, userId, sorting, reverse, maxResultCount);
CurrentTenant.Id, userId, sorting, reverse, maxResultCount, cancellationToken: Context.ConnectionAborted);
return new ListResultDto<LastChatMessage>(messages);
}
@ -144,7 +146,7 @@ namespace LINGYUN.Abp.IM.SignalR.Hubs
bool reverse = false)
{
var userFriends = await FriendStore
.GetListAsync(CurrentTenant.Id, userId, sorting, reverse);
.GetListAsync(CurrentTenant.Id, userId, sorting, reverse, cancellationToken: Context.ConnectionAborted);
return new ListResultDto<UserFriend>(userFriends);
}
@ -156,7 +158,7 @@ namespace LINGYUN.Abp.IM.SignalR.Hubs
Guid friendId,
string remarkName = "")
{
await FriendStore.AddMemberAsync(tenantId, userId, friendId, remarkName);
await FriendStore.AddRequestAsync(tenantId, userId, friendId, remarkName);
}
[HubMethodName("RemoveFriend")]
@ -166,7 +168,7 @@ namespace LINGYUN.Abp.IM.SignalR.Hubs
Guid friendId,
string remarkName = "")
{
await FriendStore.RemoveMemberAsync(tenantId, userId, friendId);
await FriendStore.RemoveMemberAsync(tenantId, userId, friendId, cancellationToken: Context.ConnectionAborted);
}
/// <summary>
@ -178,7 +180,7 @@ namespace LINGYUN.Abp.IM.SignalR.Hubs
public virtual async Task SendMessageAsync(ChatMessage chatMessage)
{
// 持久化
await MessageStore.StoreMessageAsync(chatMessage);
await MessageStore.StoreMessageAsync(chatMessage, cancellationToken: Context.ConnectionAborted);
if (!chatMessage.GroupId.IsNullOrWhiteSpace())
{
@ -199,7 +201,7 @@ namespace LINGYUN.Abp.IM.SignalR.Hubs
return;
}
await signalRClient.SendAsync("getChatMessage", chatMessage);
await signalRClient.SendAsync("getChatMessage", chatMessage, cancellationToken: Context.ConnectionAborted);
}
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!");
continue;
}
await signalRClient.SendAsync("getChatMessage", chatMessage);
await signalRClient.SendAsync("getChatMessage", chatMessage, cancellationToken: Context.ConnectionAborted);
}
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.RealTime.Client;
using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Immutable;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
namespace LINGYUN.Abp.IM.SignalR.Messages
{
[Dependency(ServiceLifetime.Transient, ReplaceServices = true)]
[ExposeServices(typeof(IMessageSender))]
public class SignalRMessageSender : MessageSenderBase
public class SignalRMessageSenderProvider : MessageSenderProviderBase
{
public override string Name => "SignalR";
private readonly IOnlineClientManager _onlineClientManager;
private readonly IHubContext<MessagesHub> _hubContext;
public SignalRMessageSender(
public SignalRMessageSenderProvider(
IOnlineClientManager onlineClientManager,
IHubContext<MessagesHub> hubContext,
IMessageStore messageStore,
ILogger<SignalRMessageSender> logger)
: base(messageStore, logger)
IServiceProvider serviceProvider)
: base(serviceProvider)
{
_hubContext = hubContext;
_onlineClientManager = onlineClientManager;

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

@ -9,6 +9,7 @@
<ItemGroup>
<PackageReference Include="Volo.Abp.Auditing" Version="3.2.0" />
<PackageReference Include="Volo.Abp.EventBus" Version="3.2.0" />
</ItemGroup>
</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.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
namespace LINGYUN.Abp.IM.Contract
@ -16,7 +17,8 @@ namespace LINGYUN.Abp.IM.Contract
Task<bool> IsFriendAsync(
Guid? tenantId,
Guid userId,
Guid friendId
Guid friendId,
CancellationToken cancellationToken = default
);
/// <summary>
/// 查询好友列表
@ -30,7 +32,8 @@ namespace LINGYUN.Abp.IM.Contract
Guid? tenantId,
Guid userId,
string sorting = nameof(UserFriend.UserId),
bool reverse = false
bool reverse = false,
CancellationToken cancellationToken = default
);
/// <summary>
/// 获取好友数量
@ -42,7 +45,8 @@ namespace LINGYUN.Abp.IM.Contract
Task<int> GetCountAsync(
Guid? tenantId,
Guid userId,
string filter = "");
string filter = "",
CancellationToken cancellationToken = default);
/// <summary>
/// 获取好友列表
/// </summary>
@ -61,7 +65,8 @@ namespace LINGYUN.Abp.IM.Contract
string sorting = nameof(UserFriend.UserId),
bool reverse = false,
int skipCount = 0,
int maxResultCount = 10);
int maxResultCount = 10,
CancellationToken cancellationToken = default);
/// <summary>
/// 获取最近联系好友列表
/// </summary>
@ -74,7 +79,8 @@ namespace LINGYUN.Abp.IM.Contract
Guid? tenantId,
Guid userId,
int skipCount = 0,
int maxResultCount = 10);
int maxResultCount = 10,
CancellationToken cancellationToken = default);
/// <summary>
/// 获取好友信息
/// </summary>
@ -85,20 +91,36 @@ namespace LINGYUN.Abp.IM.Contract
Task<UserFriend> GetMemberAsync(
Guid? tenantId,
Guid userId,
Guid friendId);
Guid friendId,
CancellationToken cancellationToken = default);
/// <summary>
/// 添加好友
/// </summary>
/// <param name="tenantId"></param>
/// <param name="userId"></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>
/// <returns></returns>
Task<UserAddFriendResult> AddMemberAsync(
Task<UserAddFriendResult> AddRequestAsync(
Guid? tenantId,
Guid userId,
Guid friendId,
string remarkName = "");
string remarkName = "",
string description = "",
CancellationToken cancellationToken = default);
/// <summary>
/// 移除好友
/// </summary>
@ -109,7 +131,8 @@ namespace LINGYUN.Abp.IM.Contract
Task RemoveMemberAsync(
Guid? tenantId,
Guid userId,
Guid friendId);
Guid friendId,
CancellationToken cancellationToken = default);
/// <summary>
/// 添加黑名单
/// </summary>
@ -120,7 +143,8 @@ namespace LINGYUN.Abp.IM.Contract
Task AddShieldMemberAsync(
Guid? tenantId,
Guid userId,
Guid friendId);
Guid friendId,
CancellationToken cancellationToken = default);
/// <summary>
/// 移除黑名单
/// </summary>
@ -131,6 +155,7 @@ namespace LINGYUN.Abp.IM.Contract
Task RemoveShieldMemberAsync(
Guid? tenantId,
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.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
namespace LINGYUN.Abp.IM.Group
@ -13,7 +14,11 @@ namespace LINGYUN.Abp.IM.Group
/// <param name="groupId"></param>
/// <param name="userId"></param>
/// <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>
@ -21,28 +26,41 @@ namespace LINGYUN.Abp.IM.Group
/// <param name="groupId"></param>
/// <param name="userId"></param>
/// <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>
/// <param name="tenantId"></param>
/// <param name="userId"></param>
/// <returns></returns>
Task<IEnumerable<Group>> GetUserGroupsAsync(Guid? tenantId, Guid userId);
Task<IEnumerable<Group>> GetUserGroupsAsync(
Guid? tenantId,
Guid userId,
CancellationToken cancellationToken = default);
/// <summary>
/// 获取群组成员列表
/// </summary>
/// <param name="tenantId"></param>
/// <param name="groupId"></param>
/// <returns></returns>
Task<IEnumerable<GroupUserCard>> GetMembersAsync(Guid? tenantId, long groupId);
Task<IEnumerable<GroupUserCard>> GetMembersAsync(
Guid? tenantId,
long groupId,
CancellationToken cancellationToken = default);
/// <summary>
/// 获取群组成员数
/// </summary>
/// <param name="tenantId"></param>
/// <param name="groupId"></param>
/// <returns></returns>
Task<int> GetMembersCountAsync(Guid? tenantId, long groupId);
Task<int> GetMembersCountAsync(
Guid? tenantId,
long groupId,
CancellationToken cancellationToken = default);
/// <summary>
/// 获取通讯组用户
/// </summary>
@ -59,7 +77,8 @@ namespace LINGYUN.Abp.IM.Group
string sorting = nameof(GroupUserCard.UserId),
bool reverse = false,
int skipCount = 0,
int maxResultCount = 10);
int maxResultCount = 10,
CancellationToken cancellationToken = default);
/// <summary>
/// 用户加入通讯组
/// </summary>
@ -67,7 +86,12 @@ namespace LINGYUN.Abp.IM.Group
/// <param name="userId"></param>
/// <param name="groupId"></param>
/// <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>
@ -75,6 +99,10 @@ namespace LINGYUN.Abp.IM.Group
/// <param name="userId"></param>
/// <param name="groupId"></param>
/// <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>
public DateTime SendTime { get; set; }
/// <summary>
/// 是否匿名发送
/// 是否匿名发送(存储在扩展字段)
/// </summary>
public bool IsAnonymous { get; set; }
/// <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.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
namespace LINGYUN.Abp.IM.Messages
@ -13,7 +14,9 @@ namespace LINGYUN.Abp.IM.Messages
/// <param name="formUserId"></param>
/// <param name="toUserId"></param>
/// <returns></returns>
Task StoreMessageAsync(ChatMessage chatMessage);
Task StoreMessageAsync(
ChatMessage chatMessage,
CancellationToken cancellationToken = default);
/// <summary>
/// 获取群组聊天记录总数
/// </summary>
@ -26,7 +29,8 @@ namespace LINGYUN.Abp.IM.Messages
Guid? tenantId,
long groupId,
string filter = "",
MessageType? type = null);
MessageType? type = null,
CancellationToken cancellationToken = default);
/// <summary>
/// 获取群组聊天记录
/// </summary>
@ -47,7 +51,8 @@ namespace LINGYUN.Abp.IM.Messages
bool reverse = true,
MessageType? type = null,
int skipCount = 0,
int maxResultCount = 10);
int maxResultCount = 10,
CancellationToken cancellationToken = default);
/// <summary>
/// 获取上一次通讯消息记录
/// </summary>
@ -62,7 +67,8 @@ namespace LINGYUN.Abp.IM.Messages
Guid userId,
string sorting = nameof(LastChatMessage.SendTime),
bool reverse = true,
int maxResultCount = 10
int maxResultCount = 10,
CancellationToken cancellationToken = default
);
/// <summary>
/// 获取与某个用户的聊天记录总数
@ -78,7 +84,8 @@ namespace LINGYUN.Abp.IM.Messages
Guid sendUserId,
Guid receiveUserId,
string filter = "",
MessageType? type = null);
MessageType? type = null,
CancellationToken cancellationToken = default);
/// <summary>
/// 获取与某个用户的聊天记录
/// </summary>
@ -95,6 +102,7 @@ namespace LINGYUN.Abp.IM.Messages
bool reverse = true,
MessageType? type = null,
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 System.Threading.Tasks;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Uow;
using Volo.Abp.Users;
namespace LINGYUN.Abp.Notifications.SignalR.Hubs
@ -16,27 +17,49 @@ namespace LINGYUN.Abp.Notifications.SignalR.Hubs
protected override async Task OnClientConnectedAsync(IOnlineClient client)
{
await base.OnClientConnectedAsync(client);
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)
{
await base.OnClientDisconnectedAsync(client);
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")]
public virtual async Task<ListResultDto<NotificationInfo>> GetNotificationAsync(
NotificationReadState readState = NotificationReadState.UnRead, int maxResultCount = 10)
public virtual async Task<ListResultDto<NotificationInfo>> GetNotificationAsync()
{
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);
}
@ -44,7 +67,13 @@ namespace LINGYUN.Abp.Notifications.SignalR.Hubs
[HubMethodName("ChangeState")]
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.Immutable;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace LINGYUN.Abp.Notifications.SignalR
@ -29,69 +30,41 @@ namespace LINGYUN.Abp.Notifications.SignalR
_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)
{
// 返回标准数据给前端
notification.Data = NotificationData.ToStandardData(notification.Data);
var singalRGroup = _hubContext.Clients.Group(tenantId.ToString());
var groupName = notification.TenantId?.ToString() ?? "Global";
var singalRGroup = _hubContext.Clients.Group(groupName);
if (singalRGroup == null)
{
Logger.LogDebug("Can not get group " + tenantId + " from SignalR hub!");
Logger.LogDebug("Can not get group " + groupName + " from SignalR hub!");
return;
}
// 租户通知群发
Logger.LogDebug($"Found a singalr group, begin senging notifications");
await singalRGroup.SendAsync("getNotification", notification);
await singalRGroup.SendAsync("getNotification", notification, cancellationToken);
}
else
{
// 返回标准数据给前端
notification.Data = NotificationData.ToStandardData(notification.Data);
foreach (var identifier in identifiers)
var onlineClients = _onlineClientManager.GetAllClients(client => identifiers.Any(ids => client.UserId == ids.UserId));
var onlineClientConnectionIds = onlineClients.Select(client => client.ConnectionId).ToImmutableArray();
try
{
Logger.LogDebug($"Find online client with user {identifier.UserId} - {identifier.UserName}");
var onlineClientContext = new OnlineClientContext(notification.TenantId, identifier.UserId);
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)
var signalRClients = _hubContext.Clients.Clients(onlineClientConnectionIds);
if (signalRClients == null)
{
Logger.LogWarning("Could not send notifications to user: {0}", identifier.UserId);
Logger.LogWarning("Send to user notifications error: {0}", ex.Message);
Logger.LogDebug("Can not get users connection from SignalR hub!");
return;
}
//foreach (var onlineClient in onlineClients)
//{
// try
// {
// Logger.LogDebug($"Find online client {onlineClient.UserId} - {onlineClient.ConnectionId}");
// var signalRClient = _hubContext.Clients.Client(onlineClient.ConnectionId);
// 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);
// }
//}
Logger.LogDebug($"Found a singalr client, begin senging notifications");
await signalRClients.SendAsync("getNotification", notification, cancellationToken);
}
catch (Exception ex)
{
Logger.LogWarning("Could not send notifications to all users");
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>
<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.Notifications\LINGYUN.Abp.Notifications.csproj" />
</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
{
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 System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.Features;
namespace LINGYUN.Abp.Notifications.WeChat.WeApp
{
@ -13,8 +16,13 @@ namespace LINGYUN.Abp.Notifications.WeChat.WeApp
public class WeChatWeAppNotificationPublishProvider : NotificationPublishProvider
{
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 AbpWeChatWeAppNotificationOptions Options { get; }
public WeChatWeAppNotificationPublishProvider(
@ -27,32 +35,39 @@ namespace LINGYUN.Abp.Notifications.WeChat.WeApp
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,
// 如果不是,需要自行处理openid获取逻辑
// step2 调用微信消息推送接口
// 微信不支持推送到所有用户,需要获取订阅列表再发送
// 微信不支持推送到所有用户
// 在小程序里用户订阅消息后通过 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)
{
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);
if (templateId.IsNullOrWhiteSpace())
{
Logger.LogWarning("Wechat weapp template id be empty, can not send notification!");
return;
}
Logger.LogDebug($"Get wechat weapp template id: {templateId}");
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);
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);
// 写入模板数据
weChatWeAppNotificationData.WriteStandardData(NotificationData.ToStandardData(Options.DefaultMsgPrefix, notification.Data));
Logger.LogDebug($"Sending wechat weapp notification: {notification.Name}");
// 发送小程序订阅消息
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.Abstractions;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.Net.Http;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Features;
using Volo.Abp.Json;
namespace LINGYUN.Abp.Notifications.WeChat.WeApp
@ -31,7 +35,14 @@ namespace LINGYUN.Abp.Notifications.WeChat.WeApp
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 requestParamters = new Dictionary<string, string>
@ -41,7 +52,7 @@ namespace LINGYUN.Abp.Notifications.WeChat.WeApp
var weChatSendNotificationUrl = "https://api.weixin.qq.com";
var weChatSendNotificationPath = "/cgi-bin/message/subscribe/send";
var requestUrl = BuildRequestUrl(weChatSendNotificationUrl, weChatSendNotificationPath, requestParamters);
var responseContent = await MakeRequestAndGetResultAsync(requestUrl, notificationData);
var responseContent = await MakeRequestAndGetResultAsync(requestUrl, notificationData, cancellationToken);
var weChatSenNotificationResponse = JsonSerializer.Deserialize<WeChatSendNotificationResponse>(responseContent);
if (!weChatSenNotificationResponse.IsSuccessed)
@ -52,7 +63,7 @@ namespace LINGYUN.Abp.Notifications.WeChat.WeApp
// 失败是否抛出异常
// 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 sendDataContent = JsonSerializer.Serialize(notificationData);
@ -62,7 +73,7 @@ namespace LINGYUN.Abp.Notifications.WeChat.WeApp
Content = requestContent
};
var response = await client.SendAsync(requestMessage);
var response = await client.SendAsync(requestMessage, cancellationToken);
if (!response.IsSuccessStatusCode)
{
throw new AbpException($"WeChat send subscribe message http request service returns error! HttpStatusCode: {response.StatusCode}, ReasonPhrase: {response.ReasonPhrase}");

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

@ -22,11 +22,6 @@ namespace LINGYUN.Abp.Notifications
AutoAddDefinitionProviders(context.Services);
}
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.AddTransient<INotificationDispatcher, DefaultNotificationDispatcher>();
}
public override void OnApplicationInitialization(ApplicationInitializationContext context)
{
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
{
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
{
[NotNull]
NotificationDefinition Get([NotNull] string category);
NotificationDefinition Get([NotNull] string name);
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>
[Obsolete("Notification system redesigned, publisher interface deactivated, please use INotificationSender")]
public interface INotificationDispatcher
{
/// <summary>
/// 发送通知
/// </summary>
/// <param name="notificationName">通知名称</param>
/// <param name="data">数据</param>
/// <param name="tenantId">租户</param>
/// <param name="notificationSeverity">级别</param>
/// <returns></returns>
Task DispatchAsync(NotificationName notificationName, NotificationData data, Guid? tenantId = null,
NotificationSeverity notificationSeverity = NotificationSeverity.Info);
///// <summary>
///// 发送通知
///// </summary>
///// <param name="notificationName">通知名称</param>
///// <param name="data">数据</param>
///// <param name="tenantId">租户</param>
///// <param name="notificationSeverity">级别</param>
///// <returns></returns>
//Task DispatchAsync(NotificationName notificationName, NotificationData data, Guid? tenantId = null,
// NotificationSeverity notificationSeverity = NotificationSeverity.Info);
/// <summary>
/// 发送通知事件
/// </summary>
/// <param name="notificationName">通知名称</param>
/// <param name="data">数据</param>
/// <param name="tenantId">租户</param>
/// <param name="notificationSeverity">级别</param>
/// <returns></returns>
Task DispatchEventAsync(NotificationName notificationName, NotificationData data, Guid? tenantId = null,
NotificationSeverity notificationSeverity = NotificationSeverity.Info);
///// <summary>
///// 发送通知事件
///// </summary>
///// <param name="notificationName">通知名称</param>
///// <param name="data">数据</param>
///// <param name="tenantId">租户</param>
///// <param name="notificationSeverity">级别</param>
///// <returns></returns>
//Task DispatchEventAsync(NotificationName notificationName, NotificationData data, Guid? tenantId = null,
// 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.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
namespace LINGYUN.Abp.Notifications
{
public interface INotificationStore
{
Task InsertUserSubscriptionAsync(Guid? tenantId, UserIdentifier identifier, string notificationName);
Task InsertUserSubscriptionAsync(Guid? tenantId, IEnumerable<UserIdentifier> identifiers, string notificationName);
Task DeleteUserSubscriptionAsync(Guid? tenantId, Guid userId, string notificationName);
Task DeleteAllUserSubscriptionAsync(Guid? tenantId, string notificationName);
Task DeleteUserSubscriptionAsync(Guid? tenantId, IEnumerable<UserIdentifier> identifiers, string notificationName);
Task<List<NotificationSubscriptionInfo>> GetSubscriptionsAsync(Guid? tenantId, string notificationName);
Task<List<NotificationSubscriptionInfo>> GetUserSubscriptionsAsync(Guid? tenantId, Guid userId);
Task<List<NotificationSubscriptionInfo>> GetUserSubscriptionsAsync(Guid? tenantId, string userName);
Task<bool> IsSubscribedAsync(Guid? tenantId, Guid userId, string notificationName);
Task InsertNotificationAsync(NotificationInfo notification);
Task DeleteNotificationAsync(NotificationInfo notification);
Task DeleteNotificationAsync(int batchCount);
Task InsertUserNotificationAsync(NotificationInfo notification, Guid userId);
Task InsertUserNotificationsAsync(NotificationInfo notification, IEnumerable<Guid> userIds);
Task DeleteUserNotificationAsync(Guid? tenantId, Guid userId, long notificationId);
Task<NotificationInfo> GetNotificationOrNullAsync(Guid? tenantId, long notificationId);
Task<List<NotificationInfo>> GetUserNotificationsAsync(Guid? tenantId, Guid userId, NotificationReadState readState = NotificationReadState.UnRead, int maxResultCount = 10);
Task ChangeUserNotificationReadStateAsync(Guid? tenantId, Guid userId, long notificationId, NotificationReadState readState);
Task InsertUserSubscriptionAsync(
Guid? tenantId,
UserIdentifier identifier,
string notificationName,
CancellationToken cancellationToken = default);
Task InsertUserSubscriptionAsync(
Guid? tenantId,
IEnumerable<UserIdentifier> identifiers,
string notificationName,
CancellationToken cancellationToken = default);
Task DeleteUserSubscriptionAsync(
Guid? tenantId,
Guid userId,
string notificationName,
CancellationToken cancellationToken = default);
Task DeleteAllUserSubscriptionAsync(
Guid? tenantId,
string notificationName,
CancellationToken cancellationToken = default);
Task DeleteUserSubscriptionAsync(
Guid? tenantId,
IEnumerable<UserIdentifier> identifiers,
string notificationName,
CancellationToken cancellationToken = default);
Task<List<NotificationSubscriptionInfo>> GetUserSubscriptionsAsync(
Guid? tenantId,
string notificationName,
IEnumerable<UserIdentifier> identifiers = null,
CancellationToken cancellationToken = default);
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.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
namespace LINGYUN.Abp.Notifications
@ -16,7 +17,11 @@ namespace LINGYUN.Abp.Notifications
/// <param name="userId">用户标识</param>
/// <param name="notificationName">通知名称</param>
/// <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>
@ -24,7 +29,11 @@ namespace LINGYUN.Abp.Notifications
/// <param name="identifier">用户标识</param>
/// <param name="notificationName">通知名称</param>
/// <returns></returns>
Task SubscribeAsync(Guid? tenantId, UserIdentifier identifier, string notificationName);
Task SubscribeAsync(
Guid? tenantId,
UserIdentifier identifier,
string notificationName,
CancellationToken cancellationToken = default);
/// <summary>
/// 订阅通知
/// </summary>
@ -32,14 +41,21 @@ namespace LINGYUN.Abp.Notifications
/// <param name="identifiers">用户标识列表</param>
/// <param name="notificationName">通知名称</param>
/// <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>
/// <param name="tenantId">租户</param>
/// <param name="notificationName">通知名称</param>
/// <returns></returns>
Task UnsubscribeAllAsync(Guid? tenantId, string notificationName);
Task UnsubscribeAllAsync(
Guid? tenantId,
string notificationName,
CancellationToken cancellationToken = default);
/// <summary>
/// 取消订阅
/// </summary>
@ -47,7 +63,11 @@ namespace LINGYUN.Abp.Notifications
/// <param name="identifier">用户标识</param>
/// <param name="notificationName">通知名称</param>
/// <returns></returns>
Task UnsubscribeAsync(Guid? tenantId, UserIdentifier identifier, string notificationName);
Task UnsubscribeAsync(
Guid? tenantId,
UserIdentifier identifier,
string notificationName,
CancellationToken cancellationToken = default);
/// <summary>
/// 取消订阅
/// </summary>
@ -55,27 +75,42 @@ namespace LINGYUN.Abp.Notifications
/// <param name="identifiers">用户标识列表</param>
/// <param name="notificationName">通知名称</param>
/// <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>
/// <param name="tenantId">租户</param>
/// <param name="notificationName">通知名称</param>
/// <param name="identifiers">需要检查的用户列表</param>
/// <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>
/// <param name="tenantId">租户</param>
/// <param name="userId">用户标识</param>
/// <returns></returns>
Task<List<NotificationSubscriptionInfo>> GetUserSubscriptionsAsync(Guid? tenantId, Guid userId);
Task<List<NotificationSubscriptionInfo>> GetUserSubscriptionsAsync(
Guid? tenantId,
Guid userId,
CancellationToken cancellationToken = default);
/// <summary>
/// 获取用户订阅列表
/// </summary>
/// <param name="tenantId">租户</param>
/// <param name="userName">用户名</param>
/// <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.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
@ -15,56 +16,89 @@ namespace LINGYUN.Abp.Notifications.Internal
_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;
}
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)
{
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>
/// <remarks>
/// TODO: 2020-10-29 针对不同语言的用户,如果在发布时期就本地化语言是错误的设计
/// 把通知的标题和内容设计为 <see cref="Volo.Abp.Validation.StringValues.LocalizableStringInfo"/> 让客户端自行本地化
/// 把通知的标题和内容设计为 <see cref="LocalizableStringInfo"/> 让客户端自行本地化
/// </remarks>
public class NotificationData
{
public const string NotificationKey = "N:G";
public const string UserIdNotificationKey = "N:UI";
public const string UserNameNotificationKey = "N:UN";
public const string TenantNotificationKey = "N:T";
public const string LocalizerKey = "localizer";
public virtual string Type => GetType().FullName;
public object this[string key]
@ -55,30 +52,35 @@ namespace LINGYUN.Abp.Notifications
public NotificationData()
{
_properties = new Dictionary<string, object>();
TrySetData(LocalizerKey, false);
}
public static NotificationData CreateNotificationData()
{
var data = new NotificationData();
data.TrySetData(NotificationKey, "AbpNotification");
return data;
}
public static NotificationData CreateUserNotificationData(Guid userId, string userName)
{
var data = new NotificationData();
data.TrySetData(UserIdNotificationKey, userId);
data.TrySetData(UserNameNotificationKey, userName);
return data;
}
public static NotificationData CreateTenantNotificationData(Guid tenantId)
/// <summary>
/// 写入本地化的消息数据
/// </summary>
/// <param name="title"></param>
/// <param name="message"></param>
/// <param name="createTime"></param>
/// <param name="formUser"></param>
/// <param name="description"></param>
/// <returns></returns>
public NotificationData WriteLocalizedData(
LocalizableStringInfo title,
LocalizableStringInfo message,
DateTime createTime,
string formUser,
LocalizableStringInfo description = null)
{
var data = new NotificationData();
data.TrySetData(TenantNotificationKey, tenantId);
return data;
TrySetData("title", title);
TrySetData("message", message);
TrySetData("formUser", formUser);
TrySetData("createTime", createTime);
TrySetData(LocalizerKey, true);
if (description != null)
{
TrySetData("description", description);
}
return this;
}
/// <summary>
/// 写入标准数据
/// </summary>
@ -86,13 +88,16 @@ namespace LINGYUN.Abp.Notifications
/// <param name="message">内容</param>
/// <param name="createTime">创建时间</param>
/// <param name="formUser">来源用户</param>
/// <param name="description">附加说明</param>
/// <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("message", message);
TrySetData("description", description);
TrySetData("formUser", formUser);
TrySetData("createTime", createTime);
TrySetData(LocalizerKey, false);
return this;
}
/// <summary>
@ -105,6 +110,7 @@ namespace LINGYUN.Abp.Notifications
public NotificationData WriteStandardData(string prefix, string key, object value)
{
TrySetData(string.Concat(prefix, key), value);
TrySetData(LocalizerKey, false);
return this;
}
/// <summary>
@ -117,8 +123,10 @@ namespace LINGYUN.Abp.Notifications
var data = new NotificationData();
data.TrySetData("title", sourceData.TryGetData("title"));
data.TrySetData("message", sourceData.TryGetData("message"));
data.TrySetData("description", sourceData.TryGetData("description"));
data.TrySetData("formUser", sourceData.TryGetData("formUser"));
data.TrySetData("createTime", sourceData.TryGetData("createTime"));
data.TrySetData(LocalizerKey, sourceData.TryGetData(LocalizerKey));
return data;
}
/// <summary>
@ -154,29 +162,20 @@ namespace LINGYUN.Abp.Notifications
{
if (value != null && !Properties.ContainsKey(key))
{
Properties[key] = value;
Properties.Add(key, value);
}
Properties[key] = value;
}
public bool HasUserNotification(out Guid userId, out string userName)
{
userName = "";
if (Properties.TryGetValue(UserIdNotificationKey, out object userKey))
{
userId = (Guid)userKey;
var name = TryGetData(UserNameNotificationKey);
userName = name?.ToString() ?? userName;
return true;
}
return false;
}
public bool HasTenantNotification(out Guid tenantId)
/// <summary>
/// 需要本地化
/// </summary>
/// <returns></returns>
public bool NeedLocalizer()
{
if (Properties.TryGetValue(TenantNotificationKey, out object tenantKey))
var localizer = TryGetData(LocalizerKey);
if (localizer != null && localizer is bool needLocalizer)
{
tenantId = (Guid)tenantKey;
return true;
return needLocalizer;
}
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 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)
@ -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;
}

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

@ -3,17 +3,11 @@ using System;
using System.Collections.Generic;
using Volo.Abp;
using Volo.Abp.Localization;
using Volo.Abp.MultiTenancy;
/*
*
* ,,,Catalog
* Prefix
*
* TODO: 2020-08-26 ?
* 宿,
* NotificationData[FormUser]
* NotificationData[FormTenant]
* NotificationData[FormGlobal]
* 2020-10-29
* INotificationSender指定接收者,,,()
*/
namespace LINGYUN.Abp.Notifications
@ -21,10 +15,10 @@ namespace LINGYUN.Abp.Notifications
public class NotificationDefinition
{
/// <summary>
/// 通知类目
/// 通知名称
/// </summary>
[NotNull]
public string CateGory { get; set; }
public string Name { get; set; }
/// <summary>
/// 通知显示名称
/// </summary>
@ -58,15 +52,15 @@ namespace LINGYUN.Abp.Notifications
public List<string> Providers { get; }
public NotificationDefinition(
string category,
string name,
ILocalizableString displayName = null,
ILocalizableString description = null,
NotificationType notificationType = NotificationType.Application,
NotificationLifetime lifetime = NotificationLifetime.Persistent,
bool allowSubscriptionToClients = false)
{
CateGory = category;
DisplayName = displayName ?? new FixedLocalizableString(category);
Name = name;
DisplayName = displayName ?? new FixedLocalizableString(name);
Description = description;
NotificationLifetime = lifetime;
NotificationType = notificationType;
@ -84,5 +78,10 @@ namespace LINGYUN.Abp.Notifications
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 Volo.Abp;
using Volo.Abp.Localization;
using Volo.Abp.MultiTenancy;
namespace LINGYUN.Abp.Notifications
{
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 System;
using System.Collections.Generic;
@ -12,51 +11,88 @@ namespace LINGYUN.Abp.Notifications
{
public class NotificationDefinitionManager : INotificationDefinitionManager, ISingletonDependency
{
protected Lazy<IDictionary<string, NotificationDefinition>> NotificationDefinitions { 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(
IOptions<AbpNotificationOptions> options,
IServiceProvider serviceProvider)
IServiceScopeFactory serviceScopeFactory)
{
ServiceProvider = serviceProvider;
_serviceScopeFactory = serviceScopeFactory;
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()
{
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>();
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
.DefinitionProviders
@ -65,11 +101,11 @@ namespace LINGYUN.Abp.Notifications
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.Collections.Generic;
using Volo.Abp.MultiTenancy;
namespace LINGYUN.Abp.Notifications
{
public class NotificationEventData
public class NotificationEventData : IMultiTenant
{
public Guid? TenantId { get; set; }
public string CateGory { get; set; }
public string Name { get; set; }
public string Id { get; set; }
public NotificationData Data { get; set; }
public DateTime CreationTime { get; set; }
public NotificationLifetime Lifetime { get; set; }
public NotificationType NotificationType { get; set; }
public NotificationSeverity NotificationSeverity { get; set; }
public NotificationSeverity Severity { get; set; }
public List<UserIdentifier> Users { get; set; }
public NotificationEventData()
{
}
public NotificationInfo ToNotificationInfo()
{
return new NotificationInfo
{
NotificationSeverity = NotificationSeverity,
CreationTime = CreationTime,
Data = Data,
Id = Id,
Name = Name,
CateGory = CateGory,
NotificationType = NotificationType,
Lifetime = Lifetime,
TenantId = TenantId
};
Users = new List<UserIdentifier>();
}
}
}

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 string Name { get; set; }
public string CateGory { get; set; }
public string Id { get; set; }
public NotificationData Data { get; set; }
public DateTime CreationTime { get; set; }
public NotificationLifetime Lifetime { get; set; }
public NotificationType NotificationType { get; set; }
public NotificationSeverity NotificationSeverity { get; set; }
public NotificationType Type { get; set; }
public NotificationSeverity Severity { get; set; }
public NotificationInfo()
{
Data = new NotificationData();
Lifetime = NotificationLifetime.Persistent;
NotificationType = NotificationType.Application;
NotificationSeverity = NotificationSeverity.Info;
Type = NotificationType.Application;
Severity = NotificationSeverity.Info;
CreationTime = DateTime.Now;
}
public long SetId(long id)
public void SetId(long id)
{
if (Id.IsNullOrWhiteSpace())
{
Id = id.ToString();
return id;
}
return GetId();
}
public long GetId()
{
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)
{
var notification = await Store.GetNotificationOrNullAsync(args.TenantId, args.NotificationId);
notification.Data = NotificationDataConverter.Convert(notification.Data);
var notifacationDataMapping = Options.NotificationDataMappings
.GetMapItemOrNull(publishProvider.Name, notification.CateGory);
.GetMapItemOrNull(notification.Name, publishProvider.Name);
if (notifacationDataMapping != null)
{
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 System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Threading;
namespace LINGYUN.Abp.Notifications
{
@ -39,11 +41,19 @@ namespace LINGYUN.Abp.Notifications
return reference;
}
public ICancellationTokenProvider CancellationTokenProvider { get; set; }
protected NotificationPublishProvider(IServiceProvider 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.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
@ -9,92 +10,178 @@ namespace LINGYUN.Abp.Notifications
[ExposeServices(typeof(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;
}
public Task DeleteAllUserSubscriptionAsync(Guid? tenantId, string notificationName)
public Task DeleteAllUserSubscriptionAsync(
Guid? tenantId,
string notificationName,
CancellationToken cancellationToken = default)
{
return Task.CompletedTask;
}
public Task DeleteNotificationAsync(NotificationInfo notification)
public Task DeleteNotificationAsync(
NotificationInfo notification,
CancellationToken cancellationToken = default)
{
return Task.CompletedTask;
}
public Task DeleteNotificationAsync(int batchCount)
public Task DeleteNotificationAsync(
int batchCount,
CancellationToken cancellationToken = default)
{
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;
}
public Task DeleteUserSubscriptionAsync(Guid? tenantId, Guid userId, string notificationName)
public Task DeleteUserSubscriptionAsync(
Guid? tenantId,
Guid userId,
string notificationName,
CancellationToken cancellationToken = default)
{
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;
}
public Task<NotificationInfo> GetNotificationOrNullAsync(Guid? tenantId, long notificationId)
public Task<NotificationInfo> GetNotificationOrNullAsync(
Guid? tenantId,
long notificationId,
CancellationToken cancellationToken = default)
{
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>());
}
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>());
}
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>());
}
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>());
}
public Task InsertNotificationAsync(NotificationInfo notification)
public Task InsertNotificationAsync(
NotificationInfo notification,
CancellationToken cancellationToken = default)
{
return Task.CompletedTask;
}
public Task InsertUserNotificationAsync(NotificationInfo notification, Guid userId)
public Task InsertUserNotificationAsync(
NotificationInfo notification,
Guid userId,
CancellationToken cancellationToken = default)
{
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;
}
public Task InsertUserSubscriptionAsync(Guid? tenantId, UserIdentifier identifier, string notificationName)
public Task InsertUserSubscriptionAsync(
Guid? tenantId,
UserIdentifier identifier,
string notificationName,
CancellationToken cancellationToken = default)
{
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;
}
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);
}

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
{
[DependsOn(
typeof(AbpRealTimeModule),
typeof(AbpAspNetCoreSignalRModule))]
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 Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using System;
using System.Threading.Tasks;
using Volo.Abp.AspNetCore.SignalR;
using Volo.Abp.AspNetCore.WebClientInfo;
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;
protected IOnlineClientManager OnlineClientManager => LazyGetRequiredService(ref _onlineClientManager);
private IHttpContextAccessor _httpContextAccessor;
protected IHttpContextAccessor HttpContextAccessor => LazyGetRequiredService(ref _httpContextAccessor);
public override async Task OnConnectedAsync()
{
await base.OnConnectedAsync();
IOnlineClient onlineClient = CreateClientForCurrentConnection();
Logger.LogDebug("A client is connected: " + onlineClient.ToString());
OnlineClientManager.Add(onlineClient);
await OnClientConnectedAsync(onlineClient);
await OnConnectedAsync(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)
{
// 从通讯组移除
var onlineClient = OnlineClientManager.GetByConnectionIdOrNull(Context.ConnectionId);
await OnDisconnectedAsync(onlineClient);
await base.OnDisconnectedAsync(exception);
Logger.LogDebug("A client is disconnected: " + Context.ConnectionId);
try
}
public virtual async Task OnDisconnectedAsync(IOnlineClient client)
{
if (client != null)
{
// 从通讯组移除
var onlineClient = OnlineClientManager.GetByConnectionIdOrNull(Context.ConnectionId);
if(onlineClient != null)
try
{
Logger.LogDebug("A client is disconnected: " + client);
// 移除在线客户端
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()
{
return new OnlineClient(Context.ConnectionId, GetClientIpAddress(),
CurrentTenant.Id, CurrentUser.Id)
return new OnlineClient(
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
{
return HttpContextAccessor.HttpContext?.Connection?.RemoteIpAddress?.ToString();
}
catch (Exception ex)
// 角色添加进组
foreach (var role in client.Roles)
{
Logger.LogException(ex, LogLevel.Warning);
return null;
await Groups.AddToGroupAsync(client.ConnectionId, role);
}
}
protected virtual Task OnClientConnectedAsync(IOnlineClient client)
protected virtual async Task OnClientDisconnectedAsync(IOnlineClient client)
{
return Task.CompletedTask;
}
protected virtual Task OnClientDisconnectedAsync(IOnlineClient client)
{
return Task.CompletedTask;
// 角色添加进组
foreach (var role in client.Roles)
{
await Groups.RemoveFromGroupAsync(client.ConnectionId, role);
}
}
}
}

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; }
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 System;
using System.Collections.Generic;
using System.Linq.Expressions;
namespace LINGYUN.Abp.RealTime.Client
{
@ -22,6 +23,8 @@ namespace LINGYUN.Abp.RealTime.Client
IReadOnlyList<IOnlineClient> GetAllClients();
IReadOnlyList<IOnlineClient> GetAllClients(Expression<Func<IOnlineClient, bool>> predicate);
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
{
@ -15,5 +17,7 @@ namespace LINGYUN.Abp.RealTime.Client
bool Contains(string connectionId);
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.Immutable;
using System.Linq;
using System.Linq.Expressions;
using Volo.Abp.DependencyInjection;
namespace LINGYUN.Abp.RealTime.Client
@ -43,5 +46,12 @@ namespace LINGYUN.Abp.RealTime.Client
{
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]
public class OnlineClient : IOnlineClient
{
public object this[string key]
public object this[object key]
{
get { return Properties[key]; }
set { Properties[key] = value; }
@ -23,10 +23,12 @@ namespace LINGYUN.Abp.RealTime.Client
public string UserName { get; set; }
public string[] Roles { get; set; }
public DateTime ConnectTime { get; set; }
private Dictionary<string, object> _properties;
public Dictionary<string, object> Properties
private IDictionary<object, object> _properties;
public IDictionary<object, object> Properties
{
get { return _properties; }
set
@ -53,7 +55,8 @@ namespace LINGYUN.Abp.RealTime.Client
TenantId = tenantId;
UserId = userId;
Properties = new Dictionary<string, object>();
Roles = new string[0];
Properties = new Dictionary<object, object>();
}
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.Immutable;
using System.Linq;
using System.Linq.Expressions;
using Volo.Abp;
using Volo.Abp.DependencyInjection;
@ -89,10 +90,12 @@ namespace LINGYUN.Abp.RealTime.Client
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]

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" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\wechat\LINGYUN.Abp.WeChat\LINGYUN.Abp.WeChat.csproj" />
</ItemGroup>
</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
{
[DependsOn(typeof(AbpJsonModule), typeof(AbpCachingModule))]
[DependsOn(
typeof(AbpWeChatModule),
typeof(AbpJsonModule),
typeof(AbpCachingModule))]
public class AbpWeChatAuthorizationModule : AbpModule
{
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
{
public interface IWeChatOpenIdFinder
{
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;
}
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 "t:" + tenant + ",c:" + code;
return "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 IHttpClientFactory HttpClientFactory { get; }
protected IJsonSerializer JsonSerializer { get; }
protected IUserWeChatCodeFinder UserWeChatCodeFinder { get; }
protected IDistributedCache<WeChatOpenIdCacheItem> Cache { get; }
public WeChatOpenIdFinder(
ICurrentTenant currentTenant,
IJsonSerializer jsonSerializer,
IUserWeChatCodeFinder userWeChatCodeFinder,
IHttpClientFactory httpClientFactory,
IOptions<AbpWeChatOptions> options,
IDistributedCache<WeChatOpenIdCacheItem> cache)
{
CurrentTenant = currentTenant;
JsonSerializer = jsonSerializer;
UserWeChatCodeFinder = userWeChatCodeFinder;
HttpClientFactory = httpClientFactory;
Cache = cache;
@ -43,12 +46,30 @@ namespace LINGYUN.Abp.WeChat.Authorization
{
// TODO: 如果需要获取SessionKey的话呢,需要再以openid作为标识来缓存一下吗
// 或者前端保存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}");

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
{
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 System;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.Caching;
using Volo.Abp.DependencyInjection;
@ -33,18 +34,18 @@ namespace LINGYUN.Abp.WeChat.Authorization
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);
Logger.LogDebug($"WeChatTokenProvider.GetCacheItemAsync: {cacheKey}");
var cacheItem = await Cache.GetAsync(cacheKey);
var cacheItem = await Cache.GetAsync(cacheKey, token: cancellationToken);
if (cacheItem != null)
{
@ -64,7 +65,7 @@ namespace LINGYUN.Abp.WeChat.Authorization
GrantType = "client_credential"
};
var response = await client.RequestWeChatCodeTokenAsync(request);
var response = await client.RequestWeChatCodeTokenAsync(request, cancellationToken);
var responseContent = await response.Content.ReadAsStringAsync();
var weChatTokenResponse = JsonSerializer.Deserialize<WeChatTokenResponse>(responseContent);
var weChatToken = weChatTokenResponse.ToWeChatToken();
@ -78,7 +79,7 @@ namespace LINGYUN.Abp.WeChat.Authorization
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}");

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);
#endregion
#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"]);
return;
}
// TODO: 统一命名规范, 微信认证传递的 code 改为 WeChatOpenIdConsts.WeCahtCodeKey
var wechatCode = raw.Get(WeChatValidatorConsts.WeChatValidatorTokenName);
if (wechatCode.IsNullOrWhiteSpace() || wechatCode.IsNullOrWhiteSpace())
{
@ -81,7 +82,7 @@ namespace LINGYUN.Abp.IdentityServer.WeChatValidator
return;
}
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)
{
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);
// 微信登录的用户写入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>();
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 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 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": {
"Permission:MessageService": "Message service",
"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": {
"Permission:MessageService": "消息服务",
"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 bool Reverse { get; set; }
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 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