diff --git a/aspnet-core/framework/wechat/LINGYUN.Abp.Identity.WeChat.Work/LINGYUN/Abp/Identity/WeChat/Work/WeChatWorkInternalUserFinder.cs b/aspnet-core/framework/wechat/LINGYUN.Abp.Identity.WeChat.Work/LINGYUN/Abp/Identity/WeChat/Work/WeChatWorkInternalUserFinder.cs index 874050057..eb44979a6 100644 --- a/aspnet-core/framework/wechat/LINGYUN.Abp.Identity.WeChat.Work/LINGYUN/Abp/Identity/WeChat/Work/WeChatWorkInternalUserFinder.cs +++ b/aspnet-core/framework/wechat/LINGYUN.Abp.Identity.WeChat.Work/LINGYUN/Abp/Identity/WeChat/Work/WeChatWorkInternalUserFinder.cs @@ -33,14 +33,14 @@ public class WeChatWorkInternalUserFinder : IWeChatWorkInternalUserFinder return userLogin?.ProviderKey; } - public async virtual Task FindUserIdentifierAsync(string agentId, Guid userId, CancellationToken cancellationToken = default) + public async virtual Task FindUserIdentifierAsync(Guid userId, CancellationToken cancellationToken = default) { var user = await UserManager.FindByIdAsync(userId.ToString()); return GetUserOpenIdOrNull(user, AbpWeChatWorkGlobalConsts.ProviderName); } - public async virtual Task> FindUserIdentifierListAsync(string agentId, IEnumerable userIdList, CancellationToken cancellationToken = default) + public async virtual Task> FindUserIdentifierListAsync(IEnumerable userIdList, CancellationToken cancellationToken = default) { var userIdentifiers = new List(); foreach (var userId in userIdList) diff --git a/aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.Application/LINGYUN/Abp/WeChat/Work/Message/WeChatWorkMessageAppService.cs b/aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.Application/LINGYUN/Abp/WeChat/Work/Message/WeChatWorkMessageAppService.cs index 69bf0f06b..52506017b 100644 --- a/aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.Application/LINGYUN/Abp/WeChat/Work/Message/WeChatWorkMessageAppService.cs +++ b/aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.Application/LINGYUN/Abp/WeChat/Work/Message/WeChatWorkMessageAppService.cs @@ -27,16 +27,16 @@ public class WeChatWorkMessageAppService : ApplicationService, IWeChatWorkMessag public async virtual Task Handle(MessageValidationInput input) { - var allSettings = await SettingProvider.GetAllAsync( + var settings = await SettingProvider.GetAllAsync( new[] { WeChatWorkSettingNames.Connection.CorpId, WeChatWorkSettingNames.Connection.Token, WeChatWorkSettingNames.Connection.EncodingAESKey, - } ); + }); - var corpId = allSettings.FirstOrDefault(x => x.Name == WeChatWorkSettingNames.Connection.CorpId)?.Value; - var token = allSettings.FirstOrDefault(x => x.Name == WeChatWorkSettingNames.Connection.Token)?.Value; - var aesKey = allSettings.FirstOrDefault(x => x.Name == WeChatWorkSettingNames.Connection.EncodingAESKey)?.Value; + var corpId = settings.FirstOrDefault(x => x.Name == WeChatWorkSettingNames.Connection.CorpId)?.Value; + var token = settings.FirstOrDefault(x => x.Name == WeChatWorkSettingNames.Connection.Token)?.Value; + var aesKey = settings.FirstOrDefault(x => x.Name == WeChatWorkSettingNames.Connection.EncodingAESKey)?.Value; Check.NotNullOrEmpty(corpId, nameof(corpId)); Check.NotNullOrEmpty(token, nameof(token)); @@ -58,16 +58,16 @@ public class WeChatWorkMessageAppService : ApplicationService, IWeChatWorkMessag public async virtual Task Handle(MessageHandleInput input) { - var allSettings = await SettingProvider.GetAllAsync( + var settings = await SettingProvider.GetAllAsync( new[] { WeChatWorkSettingNames.Connection.CorpId, WeChatWorkSettingNames.Connection.Token, WeChatWorkSettingNames.Connection.EncodingAESKey, }); - var corpId = allSettings.FirstOrDefault(x => x.Name == WeChatWorkSettingNames.Connection.CorpId)?.Value; - var token = allSettings.FirstOrDefault(x => x.Name == WeChatWorkSettingNames.Connection.Token)?.Value; - var aesKey = allSettings.FirstOrDefault(x => x.Name == WeChatWorkSettingNames.Connection.EncodingAESKey)?.Value; + var corpId = settings.FirstOrDefault(x => x.Name == WeChatWorkSettingNames.Connection.CorpId)?.Value; + var token = settings.FirstOrDefault(x => x.Name == WeChatWorkSettingNames.Connection.Token)?.Value; + var aesKey = settings.FirstOrDefault(x => x.Name == WeChatWorkSettingNames.Connection.EncodingAESKey)?.Value; Check.NotNullOrEmpty(corpId, nameof(corpId)); Check.NotNullOrEmpty(token, nameof(token)); diff --git a/aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.AspNetCore/Microsoft/AspNetCore/Authentication/WeChat/Work/WeChatWorkOAuthConsts.cs b/aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.AspNetCore/Microsoft/AspNetCore/Authentication/WeChat/Work/WeChatWorkOAuthConsts.cs index d4b3c84be..1c34f0e55 100644 --- a/aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.AspNetCore/Microsoft/AspNetCore/Authentication/WeChat/Work/WeChatWorkOAuthConsts.cs +++ b/aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.AspNetCore/Microsoft/AspNetCore/Authentication/WeChat/Work/WeChatWorkOAuthConsts.cs @@ -5,13 +5,9 @@ namespace Microsoft.AspNetCore.Authentication.WeChat.Work; public static class WeChatWorkOAuthConsts { /// - /// 微信个人信息标识 + /// 企业微信授权名称 /// - public static string ProfileKey => AbpWeChatWorkGlobalConsts.ProfileKey; - /// - /// 微信提供者标识 - /// - public static string ProviderKey => AbpWeChatWorkGlobalConsts.ProviderName; + public static string AuthenticationScheme => AbpWeChatWorkGlobalConsts.ProviderName; /// /// 微信提供者显示名称 /// @@ -23,7 +19,11 @@ public static class WeChatWorkOAuthConsts /// /// 微信客户端内的网页登录 /// - public const string AuthorizationEndpoint = "https://login.work.weixin.qq.com/wwlogin/sso/login"; + public const string AuthorizationEndpoint = "https://open.weixin.qq.com/connect/oauth2/authorize"; + /// + /// Web网页登录 + /// + public const string AuthorizationSsoEndpoint = "https://login.work.weixin.qq.com/wwlogin/sso/login"; /// /// 用户允许授权后通过返回的code换取access_token地址 /// @@ -32,7 +32,11 @@ public static class WeChatWorkOAuthConsts /// /// 使用access_token获取用户个人信息地址 /// - public const string UserInformationEndpoint = "https://qyapi.weixin.qq.com/cgi-bin/auth/getuserinfo"; + public const string UserInfoEndpoint = "https://qyapi.weixin.qq.com/cgi-bin/auth/getuserinfo"; + /// + /// 使用access_token获取用户敏感信息地址 + /// + public const string UserDetailEndpoint = "https://qyapi.weixin.qq.com/cgi-bin/auth/getuserdetail"; public const string UserInfoScope = "snsapi_privateinfo"; diff --git a/aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.AspNetCore/Microsoft/AspNetCore/Authentication/WeChat/Work/WeChatWorkOAuthHandler.cs b/aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.AspNetCore/Microsoft/AspNetCore/Authentication/WeChat/Work/WeChatWorkOAuthHandler.cs index 85318336e..595786530 100644 --- a/aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.AspNetCore/Microsoft/AspNetCore/Authentication/WeChat/Work/WeChatWorkOAuthHandler.cs +++ b/aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.AspNetCore/Microsoft/AspNetCore/Authentication/WeChat/Work/WeChatWorkOAuthHandler.cs @@ -77,6 +77,10 @@ public class WeChatWorkOAuthHandler : OAuthHandler ? WeChatWorkOAuthConsts.UserInfoScope : WeChatWorkOAuthConsts.LoginScope; + var endpoint = isWeChatBrewserRequest + ? WeChatWorkOAuthConsts.AuthorizationEndpoint + : WeChatWorkOAuthConsts.AuthorizationSsoEndpoint; + var parameters = new Dictionary { { "appid", Options.CorpId }, @@ -91,7 +95,7 @@ public class WeChatWorkOAuthHandler : OAuthHandler parameters["state"] = state; ; - return $"{QueryHelpers.AddQueryString(Options.AuthorizationEndpoint, parameters)}"; + return $"{QueryHelpers.AddQueryString(endpoint, parameters)}"; } /// @@ -143,7 +147,11 @@ public class WeChatWorkOAuthHandler : OAuthHandler /// protected async virtual Task CreateTicketAsync(string code, ClaimsIdentity identity, AuthenticationProperties properties, OAuthTokenResponse tokens) { - var address = QueryHelpers.AddQueryString(Options.UserInformationEndpoint, new Dictionary + var userInfoEndpoint = IsWeChatBrowser() + ? WeChatWorkOAuthConsts.UserDetailEndpoint + : WeChatWorkOAuthConsts.UserInfoEndpoint; + + var address = QueryHelpers.AddQueryString(userInfoEndpoint, new Dictionary { ["access_token"] = tokens.AccessToken, ["code"] = code diff --git a/aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.AspNetCore/Microsoft/AspNetCore/Authentication/WeChat/Work/WeChatWorkOAuthOptions.cs b/aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.AspNetCore/Microsoft/AspNetCore/Authentication/WeChat/Work/WeChatWorkOAuthOptions.cs index 0a80820c1..11c8cbe80 100644 --- a/aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.AspNetCore/Microsoft/AspNetCore/Authentication/WeChat/Work/WeChatWorkOAuthOptions.cs +++ b/aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.AspNetCore/Microsoft/AspNetCore/Authentication/WeChat/Work/WeChatWorkOAuthOptions.cs @@ -12,6 +12,10 @@ public class WeChatWorkOAuthOptions : OAuthOptions /// 企业Id /// public string CorpId { get; set; } + /// + /// 访问用户敏感信息端点 + /// + public string UserDetailEndpoint { get; set; } public WeChatWorkOAuthOptions() { // 用于防止初始化错误,会在OAuthHandler.InitializeHandlerAsync中进行重写 @@ -23,7 +27,9 @@ public class WeChatWorkOAuthOptions : OAuthOptions AuthorizationEndpoint = WeChatWorkOAuthConsts.AuthorizationEndpoint; TokenEndpoint = WeChatWorkOAuthConsts.TokenEndpoint; - UserInformationEndpoint = WeChatWorkOAuthConsts.UserInformationEndpoint; + UserInformationEndpoint = WeChatWorkOAuthConsts.UserInfoEndpoint; + UserDetailEndpoint = WeChatWorkOAuthConsts.UserDetailEndpoint; + Scope.Add(WeChatWorkOAuthConsts.LoginScope); Scope.Add(WeChatWorkOAuthConsts.UserInfoScope); diff --git a/aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.AspNetCore/Microsoft/AspNetCore/Authentication/WeChatWorkAuthenticationExtensions.cs b/aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.AspNetCore/Microsoft/AspNetCore/Authentication/WeChatWorkAuthenticationExtensions.cs index 9b332c0bb..365451aa6 100644 --- a/aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.AspNetCore/Microsoft/AspNetCore/Authentication/WeChatWorkAuthenticationExtensions.cs +++ b/aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.AspNetCore/Microsoft/AspNetCore/Authentication/WeChatWorkAuthenticationExtensions.cs @@ -1,5 +1,4 @@ -using LINGYUN.Abp.WeChat.Work; -using Microsoft.AspNetCore.Authentication.WeChat.Work; +using Microsoft.AspNetCore.Authentication.WeChat.Work; using Microsoft.Extensions.DependencyInjection; using System; @@ -14,8 +13,8 @@ public static class WeChatWorkAuthenticationExtensions { return builder .AddWeChatWork( - AbpWeChatWorkGlobalConsts.AuthenticationScheme, - AbpWeChatWorkGlobalConsts.DisplayName, + WeChatWorkOAuthConsts.AuthenticationScheme, + WeChatWorkOAuthConsts.DisplayName, options => { }); } @@ -27,8 +26,8 @@ public static class WeChatWorkAuthenticationExtensions { return builder .AddWeChatWork( - AbpWeChatWorkGlobalConsts.AuthenticationScheme, - AbpWeChatWorkGlobalConsts.DisplayName, + WeChatWorkOAuthConsts.AuthenticationScheme, + WeChatWorkOAuthConsts.DisplayName, configureOptions); } @@ -42,7 +41,7 @@ public static class WeChatWorkAuthenticationExtensions return builder .AddWeChatWork( authenticationScheme, - AbpWeChatWorkGlobalConsts.DisplayName, + WeChatWorkOAuthConsts.DisplayName, configureOptions); } diff --git a/aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work/LINGYUN/Abp/WeChat/Work/AbpWeChatWorkGlobalConsts.cs b/aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work/LINGYUN/Abp/WeChat/Work/AbpWeChatWorkGlobalConsts.cs index 39315c00e..d2722e389 100644 --- a/aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work/LINGYUN/Abp/WeChat/Work/AbpWeChatWorkGlobalConsts.cs +++ b/aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work/LINGYUN/Abp/WeChat/Work/AbpWeChatWorkGlobalConsts.cs @@ -5,16 +5,12 @@ public class AbpWeChatWorkGlobalConsts /// /// 企业微信对应的Provider名称 /// - public static string ProviderName { get; set; } = "WeChat.WeCom"; + public static string ProviderName { get; set; } = "WeCom"; /// /// 企业微信授权类型 /// public static string GrantType { get; set; } = "wecom"; /// - /// 企业微信授权名称 - /// - public static string AuthenticationScheme { get; set; }= "WeCom"; - /// /// 企业微信个人信息标识 /// public static string ProfileKey { get; set; } = "wecom.profile"; diff --git a/aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work/LINGYUN/Abp/WeChat/Work/Authorize/IWeChatWorkInternalUserFinder.cs b/aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work/LINGYUN/Abp/WeChat/Work/Authorize/IWeChatWorkInternalUserFinder.cs index e9154070a..42a0511b7 100644 --- a/aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work/LINGYUN/Abp/WeChat/Work/Authorize/IWeChatWorkInternalUserFinder.cs +++ b/aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work/LINGYUN/Abp/WeChat/Work/Authorize/IWeChatWorkInternalUserFinder.cs @@ -9,23 +9,19 @@ public interface IWeChatWorkInternalUserFinder /// /// 通过用户标识查询企业微信用户标识 /// - /// /// /// /// Task FindUserIdentifierAsync( - string agentId, Guid userId, CancellationToken cancellationToken = default); /// /// 通过用户标识列表查询企业微信用户标识列表 /// - /// /// /// /// Task> FindUserIdentifierListAsync( - string agentId, IEnumerable userIdList, CancellationToken cancellationToken = default); } diff --git a/aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work/LINGYUN/Abp/WeChat/Work/Authorize/NullWeChatWorkInternalUserFinder.cs b/aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work/LINGYUN/Abp/WeChat/Work/Authorize/NullWeChatWorkInternalUserFinder.cs index a946574e2..d9ac3748b 100644 --- a/aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work/LINGYUN/Abp/WeChat/Work/Authorize/NullWeChatWorkInternalUserFinder.cs +++ b/aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work/LINGYUN/Abp/WeChat/Work/Authorize/NullWeChatWorkInternalUserFinder.cs @@ -12,7 +12,6 @@ public class NullWeChatWorkInternalUserFinder : IWeChatWorkInternalUserFinder { public readonly static IWeChatWorkInternalUserFinder Instance = new NullWeChatWorkInternalUserFinder(); public Task FindUserIdentifierAsync( - string agentId, Guid userId, CancellationToken cancellationToken = default) { @@ -21,7 +20,6 @@ public class NullWeChatWorkInternalUserFinder : IWeChatWorkInternalUserFinder } public Task> FindUserIdentifierListAsync( - string agentId, IEnumerable userIdList, CancellationToken cancellationToken = default) { diff --git a/aspnet-core/modules/realtime-notifications/LINGYUN.Abp.Notifications.Application.Contracts/LINGYUN/Abp/Notifications/Dto/NotificationProviderDto.cs b/aspnet-core/modules/realtime-notifications/LINGYUN.Abp.Notifications.Application.Contracts/LINGYUN/Abp/Notifications/Dto/NotificationProviderDto.cs new file mode 100644 index 000000000..fe5402e5a --- /dev/null +++ b/aspnet-core/modules/realtime-notifications/LINGYUN.Abp.Notifications.Application.Contracts/LINGYUN/Abp/Notifications/Dto/NotificationProviderDto.cs @@ -0,0 +1,6 @@ +namespace LINGYUN.Abp.Notifications; + +public class NotificationProviderDto +{ + public string Name { get; set; } +} diff --git a/aspnet-core/modules/realtime-notifications/LINGYUN.Abp.Notifications.Application.Contracts/LINGYUN/Abp/Notifications/INotificationAppService.cs b/aspnet-core/modules/realtime-notifications/LINGYUN.Abp.Notifications.Application.Contracts/LINGYUN/Abp/Notifications/INotificationAppService.cs index 918bd10ab..12d789ba0 100644 --- a/aspnet-core/modules/realtime-notifications/LINGYUN.Abp.Notifications.Application.Contracts/LINGYUN/Abp/Notifications/INotificationAppService.cs +++ b/aspnet-core/modules/realtime-notifications/LINGYUN.Abp.Notifications.Application.Contracts/LINGYUN/Abp/Notifications/INotificationAppService.cs @@ -5,6 +5,8 @@ namespace LINGYUN.Abp.Notifications; public interface INotificationAppService { + Task> GetAssignableProvidersAsync(); + Task> GetAssignableNotifiersAsync(); Task> GetAssignableTemplatesAsync(); diff --git a/aspnet-core/modules/realtime-notifications/LINGYUN.Abp.Notifications.Application.Contracts/LINGYUN/Abp/Notifications/Permissions/NotificationsPermissions.cs b/aspnet-core/modules/realtime-notifications/LINGYUN.Abp.Notifications.Application.Contracts/LINGYUN/Abp/Notifications/Permissions/NotificationsPermissions.cs index f7ef5041f..778559b7f 100644 --- a/aspnet-core/modules/realtime-notifications/LINGYUN.Abp.Notifications.Application.Contracts/LINGYUN/Abp/Notifications/Permissions/NotificationsPermissions.cs +++ b/aspnet-core/modules/realtime-notifications/LINGYUN.Abp.Notifications.Application.Contracts/LINGYUN/Abp/Notifications/Permissions/NotificationsPermissions.cs @@ -9,6 +9,7 @@ public class NotificationsPermissions public const string Default = GroupName + ".Notification"; public const string Delete = Default + ".Delete"; + public const string Send = Default + ".Send"; } public static class GroupDefinition diff --git a/aspnet-core/modules/realtime-notifications/LINGYUN.Abp.Notifications.Application.Contracts/LINGYUN/Abp/Notifications/Permissions/NotificationsPermissionsDefinitionProvider.cs b/aspnet-core/modules/realtime-notifications/LINGYUN.Abp.Notifications.Application.Contracts/LINGYUN/Abp/Notifications/Permissions/NotificationsPermissionsDefinitionProvider.cs index ab7751da6..7f6b614a7 100644 --- a/aspnet-core/modules/realtime-notifications/LINGYUN.Abp.Notifications.Application.Contracts/LINGYUN/Abp/Notifications/Permissions/NotificationsPermissionsDefinitionProvider.cs +++ b/aspnet-core/modules/realtime-notifications/LINGYUN.Abp.Notifications.Application.Contracts/LINGYUN/Abp/Notifications/Permissions/NotificationsPermissionsDefinitionProvider.cs @@ -47,6 +47,7 @@ public class NotificationsPermissionsDefinitionProvider : PermissionDefinitionPr var noticeGroup = group.AddPermission(NotificationsPermissions.Notification.Default, L("Permission:Notification")); noticeGroup.AddChild(NotificationsPermissions.Notification.Delete, L("Permission:Delete")); + noticeGroup.AddChild(NotificationsPermissions.Notification.Send, L("Permission:Send")); } private static LocalizableString L(string name) diff --git a/aspnet-core/modules/realtime-notifications/LINGYUN.Abp.Notifications.Application/LINGYUN/Abp/Notifications/Definitions/Notifications/NotificationDefinitionAppService.cs b/aspnet-core/modules/realtime-notifications/LINGYUN.Abp.Notifications.Application/LINGYUN/Abp/Notifications/Definitions/Notifications/NotificationDefinitionAppService.cs index 21ff6a7c2..161b89278 100644 --- a/aspnet-core/modules/realtime-notifications/LINGYUN.Abp.Notifications.Application/LINGYUN/Abp/Notifications/Definitions/Notifications/NotificationDefinitionAppService.cs +++ b/aspnet-core/modules/realtime-notifications/LINGYUN.Abp.Notifications.Application/LINGYUN/Abp/Notifications/Definitions/Notifications/NotificationDefinitionAppService.cs @@ -213,7 +213,7 @@ public class NotificationDefinitionAppService : AbpNotificationsApplicationServi } if (!string.Equals(record.Providers, allowedProviders, StringComparison.InvariantCultureIgnoreCase)) { - record.UseProviders(input.Providers.ToArray()); + record.Providers = allowedProviders; } record.ExtraProperties.Clear(); foreach (var property in input.ExtraProperties) diff --git a/aspnet-core/modules/realtime-notifications/LINGYUN.Abp.Notifications.Application/LINGYUN/Abp/Notifications/NotificationAppService.cs b/aspnet-core/modules/realtime-notifications/LINGYUN.Abp.Notifications.Application/LINGYUN/Abp/Notifications/NotificationAppService.cs index 94c93fbf7..12bae4c35 100644 --- a/aspnet-core/modules/realtime-notifications/LINGYUN.Abp.Notifications.Application/LINGYUN/Abp/Notifications/NotificationAppService.cs +++ b/aspnet-core/modules/realtime-notifications/LINGYUN.Abp.Notifications.Application/LINGYUN/Abp/Notifications/NotificationAppService.cs @@ -1,4 +1,5 @@ -using Microsoft.AspNetCore.Authorization; +using LINGYUN.Abp.Notifications.Permissions; +using Microsoft.AspNetCore.Authorization; using System.Collections.Generic; using System.Globalization; using System.Linq; @@ -14,15 +15,31 @@ public class NotificationAppService : AbpNotificationsApplicationServiceBase, IN protected ITemplateContentProvider TemplateContentProvider { get; } protected INotificationSender NotificationSender { get; } protected INotificationDefinitionManager NotificationDefinitionManager { get; } + protected INotificationPublishProviderManager NotificationPublishProviderManager { get; } public NotificationAppService( INotificationSender notificationSender, ITemplateContentProvider templateContentProvider, - INotificationDefinitionManager notificationDefinitionManager) + INotificationDefinitionManager notificationDefinitionManager, + INotificationPublishProviderManager notificationPublishProviderManager) { NotificationSender = notificationSender; TemplateContentProvider = templateContentProvider; NotificationDefinitionManager = notificationDefinitionManager; + NotificationPublishProviderManager = notificationPublishProviderManager; + } + + public virtual Task> GetAssignableProvidersAsync() + { + var providers = NotificationPublishProviderManager + .Providers + .Select(x => new NotificationProviderDto + { + Name = x.Name + }) + .ToList(); + + return Task.FromResult(new ListResultDto(providers)); } public async virtual Task> GetAssignableNotifiersAsync() @@ -95,6 +112,7 @@ public class NotificationAppService : AbpNotificationsApplicationServiceBase, IN return new ListResultDto(templates); } + [Authorize(NotificationsPermissions.Notification.Send)] public async virtual Task SendAsync(NotificationSendDto input) { var notificationData = new NotificationData(); diff --git a/aspnet-core/modules/realtime-notifications/LINGYUN.Abp.Notifications.Domain.Shared/LINGYUN/Abp/Notifications/Localization/DomainShared/en.json b/aspnet-core/modules/realtime-notifications/LINGYUN.Abp.Notifications.Domain.Shared/LINGYUN/Abp/Notifications/Localization/DomainShared/en.json index 93a508001..cf3b8bdb5 100644 --- a/aspnet-core/modules/realtime-notifications/LINGYUN.Abp.Notifications.Domain.Shared/LINGYUN/Abp/Notifications/Localization/DomainShared/en.json +++ b/aspnet-core/modules/realtime-notifications/LINGYUN.Abp.Notifications.Domain.Shared/LINGYUN/Abp/Notifications/Localization/DomainShared/en.json @@ -4,9 +4,11 @@ "Permission:Notifications": "Notification", "Permission:GroupDefinitions": "Group Definitions", "Permission:NotificationDefinitions": "Notification Definitions", + "Permission:Notification": "Manage Notification", "Permission:Create": "Create", "Permission:Edit": "Edit", "Permission:Delete": "Delete", + "Permission:Send": "Send", "Notifications:001404": "The notification template does not exist!", "Notifications:002400": "The static notification group {Name} is not allowed to change!", "Notifications:002403": "Notification that the {Name} group already exists!", @@ -46,6 +48,7 @@ "Properties": "Properties", "TemplateContent": "Template Content", "ItemWillBeDeleteOrRestoreMessage": "If the notification has been changed, it will revert to the default notification. Otherwise, the custom notification is removed.", - "Notifications:Send": "Send Notification" + "Notifications:Send": "Send Notification", + "SendSuccessfully": "Send Successfully" } } \ No newline at end of file diff --git a/aspnet-core/modules/realtime-notifications/LINGYUN.Abp.Notifications.Domain.Shared/LINGYUN/Abp/Notifications/Localization/DomainShared/zh-Hans.json b/aspnet-core/modules/realtime-notifications/LINGYUN.Abp.Notifications.Domain.Shared/LINGYUN/Abp/Notifications/Localization/DomainShared/zh-Hans.json index 2e78ec018..b2f50c5f5 100644 --- a/aspnet-core/modules/realtime-notifications/LINGYUN.Abp.Notifications.Domain.Shared/LINGYUN/Abp/Notifications/Localization/DomainShared/zh-Hans.json +++ b/aspnet-core/modules/realtime-notifications/LINGYUN.Abp.Notifications.Domain.Shared/LINGYUN/Abp/Notifications/Localization/DomainShared/zh-Hans.json @@ -4,9 +4,11 @@ "Permission:Notifications": "通知管理", "Permission:GroupDefinitions": "分组定义", "Permission:NotificationDefinitions": "通知定义", + "Permission:Notification": "管理通知", "Permission:Create": "新增", "Permission:Edit": "编辑", "Permission:Delete": "删除", + "Permission:Send": "发送通知", "Notifications:001404": "通知模板不存在!", "Notifications:002400": "静态通知分组 {Name} 不允许变更!", "Notifications:002403": "通知分组 {Name} 已经存在!", @@ -46,6 +48,7 @@ "Properties": "属性", "TemplateContent": "模板内容", "ItemWillBeDeleteOrRestoreMessage": "如果已改变通知, 将还原到默认通知。否则会删除自定义通知.", - "Notifications:Send": "发送通知" + "Notifications:Send": "发送通知", + "SendSuccessfully": "发送成功" } } \ No newline at end of file diff --git a/aspnet-core/modules/realtime-notifications/LINGYUN.Abp.Notifications.Domain/LINGYUN/Abp/Notifications/NotificationDefinitionRecord.cs b/aspnet-core/modules/realtime-notifications/LINGYUN.Abp.Notifications.Domain/LINGYUN/Abp/Notifications/NotificationDefinitionRecord.cs index bdbc91615..30a76e9b2 100644 --- a/aspnet-core/modules/realtime-notifications/LINGYUN.Abp.Notifications.Domain/LINGYUN/Abp/Notifications/NotificationDefinitionRecord.cs +++ b/aspnet-core/modules/realtime-notifications/LINGYUN.Abp.Notifications.Domain/LINGYUN/Abp/Notifications/NotificationDefinitionRecord.cs @@ -53,7 +53,7 @@ public class NotificationDefinitionRecord : BasicAggregateRoot, IHasExtraP /// /// 多个之间用;分隔 /// - public virtual string Providers { get; protected set; } + public virtual string Providers { get; set; } /// /// 允许客户端订阅 /// @@ -93,23 +93,6 @@ public class NotificationDefinitionRecord : BasicAggregateRoot, IHasExtraP AllowSubscriptionToClients = true; } - public void UseProviders(params string[] providers) - { - var currentProviders = Providers.IsNullOrWhiteSpace() - ? new List() - : Providers.Split(';').ToList(); - - if (!providers.IsNullOrEmpty()) - { - currentProviders.AddIfNotContains(providers); - } - - if (currentProviders.Any()) - { - Providers = currentProviders.JoinAsString(";"); - } - } - public bool HasSameData(NotificationDefinitionRecord otherRecord) { if (Name != otherRecord.Name) diff --git a/aspnet-core/modules/realtime-notifications/LINGYUN.Abp.Notifications.HttpApi/LINGYUN/Abp/Notifications/NotificationController.cs b/aspnet-core/modules/realtime-notifications/LINGYUN.Abp.Notifications.HttpApi/LINGYUN/Abp/Notifications/NotificationController.cs index 69e98fbae..e58a9745e 100644 --- a/aspnet-core/modules/realtime-notifications/LINGYUN.Abp.Notifications.HttpApi/LINGYUN/Abp/Notifications/NotificationController.cs +++ b/aspnet-core/modules/realtime-notifications/LINGYUN.Abp.Notifications.HttpApi/LINGYUN/Abp/Notifications/NotificationController.cs @@ -1,4 +1,5 @@ -using Microsoft.AspNetCore.Authorization; +using LINGYUN.Abp.Notifications.Permissions; +using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using System.Threading.Tasks; using Volo.Abp; @@ -24,6 +25,7 @@ public class NotificationController : AbpControllerBase, INotificationAppService [HttpPost] [Route("send")] + [Authorize(NotificationsPermissions.Notification.Send)] public virtual Task SendAsync(NotificationSendDto input) { return NotificationAppService.SendAsync(input); @@ -49,4 +51,11 @@ public class NotificationController : AbpControllerBase, INotificationAppService { return NotificationAppService.GetAssignableTemplatesAsync(); } + + [HttpGet] + [Route("assignable-providers")] + public virtual Task> GetAssignableProvidersAsync() + { + return NotificationAppService.GetAssignableProvidersAsync(); + } } diff --git a/aspnet-core/modules/realtime-notifications/LINGYUN.Abp.Notifications.WeChat.Work/LINGYUN.Abp.Notifications.WeChat.Work.csproj b/aspnet-core/modules/realtime-notifications/LINGYUN.Abp.Notifications.WeChat.Work/LINGYUN.Abp.Notifications.WeChat.Work.csproj index a797ae37a..4c4d4c2cf 100644 --- a/aspnet-core/modules/realtime-notifications/LINGYUN.Abp.Notifications.WeChat.Work/LINGYUN.Abp.Notifications.WeChat.Work.csproj +++ b/aspnet-core/modules/realtime-notifications/LINGYUN.Abp.Notifications.WeChat.Work/LINGYUN.Abp.Notifications.WeChat.Work.csproj @@ -13,6 +13,11 @@ + + + + + diff --git a/aspnet-core/modules/realtime-notifications/LINGYUN.Abp.Notifications.WeChat.Work/LINGYUN/Abp/Notifications/WeChat/Work/AbpNotificationsWeChatWorkModule.cs b/aspnet-core/modules/realtime-notifications/LINGYUN.Abp.Notifications.WeChat.Work/LINGYUN/Abp/Notifications/WeChat/Work/AbpNotificationsWeChatWorkModule.cs index 56f73d5ee..b40f9b578 100644 --- a/aspnet-core/modules/realtime-notifications/LINGYUN.Abp.Notifications.WeChat.Work/LINGYUN/Abp/Notifications/WeChat/Work/AbpNotificationsWeChatWorkModule.cs +++ b/aspnet-core/modules/realtime-notifications/LINGYUN.Abp.Notifications.WeChat.Work/LINGYUN/Abp/Notifications/WeChat/Work/AbpNotificationsWeChatWorkModule.cs @@ -1,5 +1,8 @@ using LINGYUN.Abp.WeChat.Work; +using LINGYUN.Abp.WeChat.Work.Localization; +using Volo.Abp.Localization; using Volo.Abp.Modularity; +using Volo.Abp.VirtualFileSystem; namespace LINGYUN.Abp.Notifications.WeChat.Work; @@ -10,6 +13,18 @@ public class AbpNotificationsWeChatWorkModule : AbpModule { public override void ConfigureServices(ServiceConfigurationContext context) { + Configure(options => + { + options.FileSets.AddEmbedded(); + }); + + Configure(options => + { + options.Resources + .Get() + .AddVirtualJson("/LINGYUN/Abp/Notifications/WeChat/Work/Localization/Resources"); + }); + Configure(options => { options.PublishProviders.Add(); diff --git a/aspnet-core/modules/realtime-notifications/LINGYUN.Abp.Notifications.WeChat.Work/LINGYUN/Abp/Notifications/WeChat/Work/Localization/Resources/en.json b/aspnet-core/modules/realtime-notifications/LINGYUN.Abp.Notifications.WeChat.Work/LINGYUN/Abp/Notifications/WeChat/Work/Localization/Resources/en.json new file mode 100644 index 000000000..5e0fad26c --- /dev/null +++ b/aspnet-core/modules/realtime-notifications/LINGYUN.Abp.Notifications.WeChat.Work/LINGYUN/Abp/Notifications/WeChat/Work/Localization/Resources/en.json @@ -0,0 +1,8 @@ +{ + "culture": "en", + "texts": { + "Notification:WeChatWork": "WeCom", + "Notification:WeChatWorkTest": "WeCom notification testing", + "Notification:WeChatWorkTestDesc": "Used to test wecom notification sending" + } +} \ No newline at end of file diff --git a/aspnet-core/modules/realtime-notifications/LINGYUN.Abp.Notifications.WeChat.Work/LINGYUN/Abp/Notifications/WeChat/Work/Localization/Resources/zh-Hans.json b/aspnet-core/modules/realtime-notifications/LINGYUN.Abp.Notifications.WeChat.Work/LINGYUN/Abp/Notifications/WeChat/Work/Localization/Resources/zh-Hans.json new file mode 100644 index 000000000..dcb7d3ac3 --- /dev/null +++ b/aspnet-core/modules/realtime-notifications/LINGYUN.Abp.Notifications.WeChat.Work/LINGYUN/Abp/Notifications/WeChat/Work/Localization/Resources/zh-Hans.json @@ -0,0 +1,8 @@ +{ + "culture": "zh-Hans", + "texts": { + "Notification:WeChatWork": "企业微信", + "Notification:WeChatWorkTest": "企业微信消息测试", + "Notification:WeChatWorkTestDesc": "用于测试企业微信消息发送" + } +} \ No newline at end of file diff --git a/aspnet-core/modules/realtime-notifications/LINGYUN.Abp.Notifications.WeChat.Work/LINGYUN/Abp/Notifications/WeChat/Work/WeChatWorkNotificationDefinitionProvider.cs b/aspnet-core/modules/realtime-notifications/LINGYUN.Abp.Notifications.WeChat.Work/LINGYUN/Abp/Notifications/WeChat/Work/WeChatWorkNotificationDefinitionProvider.cs new file mode 100644 index 000000000..4707533bf --- /dev/null +++ b/aspnet-core/modules/realtime-notifications/LINGYUN.Abp.Notifications.WeChat.Work/LINGYUN/Abp/Notifications/WeChat/Work/WeChatWorkNotificationDefinitionProvider.cs @@ -0,0 +1,27 @@ +using LINGYUN.Abp.WeChat.Work.Localization; +using Volo.Abp.Localization; + +namespace LINGYUN.Abp.Notifications.WeChat.Work; + +public class WeChatWorkNotificationDefinitionProvider : NotificationDefinitionProvider +{ + public override void Define(INotificationDefinitionContext context) + { + var group = context.AddGroup( + WeChatWorkNotificationNames.GroupName, + L("Notification:WeChatWork"), + L("Notification:WeChatWork")); + + group.AddNotification( + WeChatWorkNotificationNames.TestNotification, + L("Notification:WeChatWorkTest"), + L("Notification:WeChatWorkTestDesc"), + allowSubscriptionToClients: true) + .WithProviders(WeChatWorkNotificationPublishProvider.ProviderName); + } + + private static LocalizableString L(string name) + { + return LocalizableString.Create(name); + } +} diff --git a/aspnet-core/modules/realtime-notifications/LINGYUN.Abp.Notifications.WeChat.Work/LINGYUN/Abp/Notifications/WeChat/Work/WeChatWorkNotificationNames.cs b/aspnet-core/modules/realtime-notifications/LINGYUN.Abp.Notifications.WeChat.Work/LINGYUN/Abp/Notifications/WeChat/Work/WeChatWorkNotificationNames.cs new file mode 100644 index 000000000..6c7cf91a5 --- /dev/null +++ b/aspnet-core/modules/realtime-notifications/LINGYUN.Abp.Notifications.WeChat.Work/LINGYUN/Abp/Notifications/WeChat/Work/WeChatWorkNotificationNames.cs @@ -0,0 +1,7 @@ +namespace LINGYUN.Abp.Notifications.WeChat.Work; + +public static class WeChatWorkNotificationNames +{ + public const string GroupName = "WeChat.Work"; + public const string TestNotification = GroupName + ".Test"; +} diff --git a/aspnet-core/modules/realtime-notifications/LINGYUN.Abp.Notifications.WeChat.Work/LINGYUN/Abp/Notifications/WeChat/Work/WeChatWorkNotificationPublishProvider.cs b/aspnet-core/modules/realtime-notifications/LINGYUN.Abp.Notifications.WeChat.Work/LINGYUN/Abp/Notifications/WeChat/Work/WeChatWorkNotificationPublishProvider.cs index ad009be86..20fd42d54 100644 --- a/aspnet-core/modules/realtime-notifications/LINGYUN.Abp.Notifications.WeChat.Work/LINGYUN/Abp/Notifications/WeChat/Work/WeChatWorkNotificationPublishProvider.cs +++ b/aspnet-core/modules/realtime-notifications/LINGYUN.Abp.Notifications.WeChat.Work/LINGYUN/Abp/Notifications/WeChat/Work/WeChatWorkNotificationPublishProvider.cs @@ -3,6 +3,7 @@ using LINGYUN.Abp.WeChat.Work.Authorize; using LINGYUN.Abp.WeChat.Work.Features; using LINGYUN.Abp.WeChat.Work.Messages; using LINGYUN.Abp.WeChat.Work.Messages.Models; +using LINGYUN.Abp.WeChat.Work.Settings; using Microsoft.Extensions.Localization; using Microsoft.Extensions.Logging; using System; @@ -11,6 +12,7 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; using Volo.Abp.Features; +using Volo.Abp.Settings; namespace LINGYUN.Abp.Notifications.WeChat.Work; public class WeChatWorkNotificationPublishProvider : NotificationPublishProvider @@ -18,24 +20,12 @@ public class WeChatWorkNotificationPublishProvider : NotificationPublishProvider public const string ProviderName = NotificationProviderNames.WechatWork; public override string Name => ProviderName; - protected IFeatureChecker FeatureChecker { get; } - protected IStringLocalizerFactory LocalizerFactory { get; } - protected IWeChatWorkMessageSender WeChatWorkMessageSender { get; } - protected IWeChatWorkInternalUserFinder WeChatWorkInternalUserFinder { get; } - protected INotificationDefinitionManager NotificationDefinitionManager { get; } - public WeChatWorkNotificationPublishProvider( - IFeatureChecker featureChecker, - IStringLocalizerFactory localizerFactory, - IWeChatWorkMessageSender weChatWorkMessageSender, - IWeChatWorkInternalUserFinder weChatWorkInternalUserFinder, - INotificationDefinitionManager notificationDefinitionManager) - { - FeatureChecker = featureChecker; - LocalizerFactory = localizerFactory; - WeChatWorkMessageSender = weChatWorkMessageSender; - WeChatWorkInternalUserFinder = weChatWorkInternalUserFinder; - NotificationDefinitionManager = notificationDefinitionManager; - } + protected IFeatureChecker FeatureChecker => ServiceProvider.LazyGetRequiredService(); + protected ISettingProvider SettingProvider => ServiceProvider.LazyGetRequiredService(); + protected IStringLocalizerFactory LocalizerFactory => ServiceProvider.LazyGetRequiredService(); + protected IWeChatWorkMessageSender WeChatWorkMessageSender => ServiceProvider.LazyGetRequiredService(); + protected IWeChatWorkInternalUserFinder WeChatWorkInternalUserFinder => ServiceProvider.LazyGetRequiredService(); + protected INotificationDefinitionManager NotificationDefinitionManager => ServiceProvider.LazyGetRequiredService(); protected async override Task CanPublishAsync(NotificationInfo notification, CancellationToken cancellationToken = default) { @@ -59,9 +49,10 @@ public class WeChatWorkNotificationPublishProvider : NotificationPublishProvider { var sendToAgentIds = new List(); var notificationDefine = await NotificationDefinitionManager.GetOrNullAsync(notification.Name); - var agentId = notification.Data.GetAgentIdOrNull() ?? notificationDefine?.GetAgentIdOrNull(); + var agentId = await SettingProvider.GetOrNullAsync(WeChatWorkSettingNames.Connection.AgentId); if (agentId.IsNullOrWhiteSpace()) { + Logger.LogWarning("Unable to send enterprise wechat messages because agentId is not set."); return; } @@ -96,7 +87,7 @@ public class WeChatWorkNotificationPublishProvider : NotificationPublishProvider } var findUserList = await WeChatWorkInternalUserFinder - .FindUserIdentifierListAsync(agentId, identifiers.Select(id => id.UserId)); + .FindUserIdentifierListAsync(identifiers.Select(id => id.UserId)); if (!findUserList.Any()) { @@ -148,6 +139,7 @@ public class WeChatWorkNotificationPublishProvider : NotificationPublishProvider return; } + message.ToUser = toUser; message.ToTag = toTag; message.ToParty = toParty; diff --git a/aspnet-core/services/LY.MicroService.Applications.Single/LY.MicroService.Applications.Single.csproj b/aspnet-core/services/LY.MicroService.Applications.Single/LY.MicroService.Applications.Single.csproj index d70f703a7..589a2a4a1 100644 --- a/aspnet-core/services/LY.MicroService.Applications.Single/LY.MicroService.Applications.Single.csproj +++ b/aspnet-core/services/LY.MicroService.Applications.Single/LY.MicroService.Applications.Single.csproj @@ -104,6 +104,7 @@ + diff --git a/aspnet-core/services/LY.MicroService.Applications.Single/MicroServiceApplicationsSingleModule.cs b/aspnet-core/services/LY.MicroService.Applications.Single/MicroServiceApplicationsSingleModule.cs index 747ee1943..e66cd9dd0 100644 --- a/aspnet-core/services/LY.MicroService.Applications.Single/MicroServiceApplicationsSingleModule.cs +++ b/aspnet-core/services/LY.MicroService.Applications.Single/MicroServiceApplicationsSingleModule.cs @@ -1,3 +1,6 @@ +using LINGYUN.Abp.Identity.WeChat.Work; +using LINGYUN.Abp.Notifications.WeChat.Work; + namespace LY.MicroService.Applications.Single; [DependsOn( @@ -19,6 +22,8 @@ namespace LY.MicroService.Applications.Single; typeof(AbpIdentityOrganizaztionUnitsModule), // 身份认证模块 微信身份标识 typeof(AbpIdentityWeChatModule), + // 身份认证模块 企业微信身份标识 + typeof(AbpIdentityWeChatWorkModule), // 身份认证模块 领域服务 typeof(AbpIdentityDomainModule), // 身份认证模块 应用服务 @@ -301,6 +306,8 @@ namespace LY.MicroService.Applications.Single; typeof(AbpNotificationsEmailingModule), // 通知模块 微信小程序 typeof(AbpNotificationsWeChatMiniProgramModule), + // 通知模块 企业微信 + typeof(AbpNotificationsWeChatWorkModule), // 多租户模块 版本 typeof(AbpMultiTenancyEditionsModule),