diff --git a/common.props b/common.props index 78e68ea..71f8492 100644 --- a/common.props +++ b/common.props @@ -1,7 +1,7 @@ latest - 2.7.0-preview.2 + 3.0.0-preview.1 $(NoWarn);CS1591 true EasyAbp Team diff --git a/docs/WeChatOfficial.md b/docs/WeChatOfficial.md index 6c6027f..327dd60 100644 --- a/docs/WeChatOfficial.md +++ b/docs/WeChatOfficial.md @@ -67,10 +67,10 @@ var result = await customMenuService.DeleteCustomMenuAsync(); 在您调用服务,或处理微信请求的事件通知回调时,若提供的 `appId` 与 Setting 中的默认值可能不同,则您需要手动实现 `IAbpWeChatOptionsProvider`,若使用 EasyAbp 封装的[微信管理模块](https://github.com/EasyAbp/WeChatManagement),则您无需再手动实现。 本模块提供的用于微信服务器通讯的 HTTP API 接口,也支持多应用和多租户,您需要使用合适的替代路由: - * `/wechat/verify` - * `/wechat/verify/tenant-id/{tenantId}` - * `/wechat/verify/app-id/{appId}` - * `/wechat/verify/tenant-id/{tenantId}/app-id/{appId}` + * `/wechat/notify` + * `/wechat/notify/tenant-id/{tenantId}` + * `/wechat/notify/app-id/{appId}` + * `/wechat/notify/tenant-id/{tenantId}/app-id/{appId}` * `/wechat/redirect-url` * `/wechat/redirect-url/tenant-id/{tenantId}` * `/wechat/redirect-url/app-id/{appId}` diff --git a/src/OpenPlatform/EasyAbp.Abp.WeChat.OpenPlatform.Abstractions/RequestHandling/Dtos/AppEventHandlingResult.cs b/src/Common/EasyAbp.Abp.WeChat.Common.Abstractions/RequestHandling/Dtos/AppEventHandlingResult.cs similarity index 87% rename from src/OpenPlatform/EasyAbp.Abp.WeChat.OpenPlatform.Abstractions/RequestHandling/Dtos/AppEventHandlingResult.cs rename to src/Common/EasyAbp.Abp.WeChat.Common.Abstractions/RequestHandling/Dtos/AppEventHandlingResult.cs index ed93b27..d7c06fc 100644 --- a/src/OpenPlatform/EasyAbp.Abp.WeChat.OpenPlatform.Abstractions/RequestHandling/Dtos/AppEventHandlingResult.cs +++ b/src/Common/EasyAbp.Abp.WeChat.Common.Abstractions/RequestHandling/Dtos/AppEventHandlingResult.cs @@ -1,7 +1,6 @@ -using EasyAbp.Abp.WeChat.Common.RequestHandling; -using JetBrains.Annotations; +using JetBrains.Annotations; -namespace EasyAbp.Abp.WeChat.OpenPlatform.RequestHandling.Dtos; +namespace EasyAbp.Abp.WeChat.Common.RequestHandling.Dtos; public class AppEventHandlingResult : WeChatRequestHandlingResult { diff --git a/src/OpenPlatform/EasyAbp.Abp.WeChat.OpenPlatform.Abstractions/RequestHandling/Dtos/IResponseToWeChatModel.cs b/src/Common/EasyAbp.Abp.WeChat.Common.Abstractions/RequestHandling/Dtos/IResponseToWeChatModel.cs similarity index 51% rename from src/OpenPlatform/EasyAbp.Abp.WeChat.OpenPlatform.Abstractions/RequestHandling/Dtos/IResponseToWeChatModel.cs rename to src/Common/EasyAbp.Abp.WeChat.Common.Abstractions/RequestHandling/Dtos/IResponseToWeChatModel.cs index c1eceb4..5c71d45 100644 --- a/src/OpenPlatform/EasyAbp.Abp.WeChat.OpenPlatform.Abstractions/RequestHandling/Dtos/IResponseToWeChatModel.cs +++ b/src/Common/EasyAbp.Abp.WeChat.Common.Abstractions/RequestHandling/Dtos/IResponseToWeChatModel.cs @@ -1,4 +1,4 @@ -namespace EasyAbp.Abp.WeChat.OpenPlatform.RequestHandling.Dtos; +namespace EasyAbp.Abp.WeChat.Common.RequestHandling.Dtos; public interface IResponseToWeChatModel { diff --git a/src/OpenPlatform/EasyAbp.Abp.WeChat.OpenPlatform.Abstractions/RequestHandling/Dtos/JsonResponseToWeChatModel.cs b/src/Common/EasyAbp.Abp.WeChat.Common.Abstractions/RequestHandling/Dtos/JsonResponseToWeChatModel.cs similarity index 61% rename from src/OpenPlatform/EasyAbp.Abp.WeChat.OpenPlatform.Abstractions/RequestHandling/Dtos/JsonResponseToWeChatModel.cs rename to src/Common/EasyAbp.Abp.WeChat.Common.Abstractions/RequestHandling/Dtos/JsonResponseToWeChatModel.cs index 0d69c20..4a87cf2 100644 --- a/src/OpenPlatform/EasyAbp.Abp.WeChat.OpenPlatform.Abstractions/RequestHandling/Dtos/JsonResponseToWeChatModel.cs +++ b/src/Common/EasyAbp.Abp.WeChat.Common.Abstractions/RequestHandling/Dtos/JsonResponseToWeChatModel.cs @@ -1,4 +1,4 @@ -namespace EasyAbp.Abp.WeChat.OpenPlatform.RequestHandling.Dtos; +namespace EasyAbp.Abp.WeChat.Common.RequestHandling.Dtos; public class JsonResponseToWeChatModel : IResponseToWeChatModel { diff --git a/src/Common/EasyAbp.Abp.WeChat.Common.Abstractions/RequestHandling/Dtos/PlainTextResponseToWeChatModel.cs b/src/Common/EasyAbp.Abp.WeChat.Common.Abstractions/RequestHandling/Dtos/PlainTextResponseToWeChatModel.cs new file mode 100644 index 0000000..f6f6a6e --- /dev/null +++ b/src/Common/EasyAbp.Abp.WeChat.Common.Abstractions/RequestHandling/Dtos/PlainTextResponseToWeChatModel.cs @@ -0,0 +1,6 @@ +namespace EasyAbp.Abp.WeChat.Common.RequestHandling.Dtos; + +public class PlainTextResponseToWeChatModel : IResponseToWeChatModel +{ + public string Content { get; set; } +} \ No newline at end of file diff --git a/src/Common/EasyAbp.Abp.WeChat.Common.Abstractions/RequestHandling/Dtos/WeChatEventRequestModel.cs b/src/Common/EasyAbp.Abp.WeChat.Common.Abstractions/RequestHandling/Dtos/WeChatEventRequestModel.cs index 88ddca4..e2331ac 100644 --- a/src/Common/EasyAbp.Abp.WeChat.Common.Abstractions/RequestHandling/Dtos/WeChatEventRequestModel.cs +++ b/src/Common/EasyAbp.Abp.WeChat.Common.Abstractions/RequestHandling/Dtos/WeChatEventRequestModel.cs @@ -11,5 +11,5 @@ public class WeChatEventRequestModel public string Timestamp { get; set; } - public string Notice { get; set; } + public string Nonce { get; set; } } \ No newline at end of file diff --git a/src/OpenPlatform/EasyAbp.Abp.WeChat.OpenPlatform.Abstractions/RequestHandling/Dtos/XmlResponseToWeChatModel.cs b/src/Common/EasyAbp.Abp.WeChat.Common.Abstractions/RequestHandling/Dtos/XmlResponseToWeChatModel.cs similarity index 61% rename from src/OpenPlatform/EasyAbp.Abp.WeChat.OpenPlatform.Abstractions/RequestHandling/Dtos/XmlResponseToWeChatModel.cs rename to src/Common/EasyAbp.Abp.WeChat.Common.Abstractions/RequestHandling/Dtos/XmlResponseToWeChatModel.cs index 68ffc60..c91f30b 100644 --- a/src/OpenPlatform/EasyAbp.Abp.WeChat.OpenPlatform.Abstractions/RequestHandling/Dtos/XmlResponseToWeChatModel.cs +++ b/src/Common/EasyAbp.Abp.WeChat.Common.Abstractions/RequestHandling/Dtos/XmlResponseToWeChatModel.cs @@ -1,4 +1,4 @@ -namespace EasyAbp.Abp.WeChat.OpenPlatform.RequestHandling.Dtos; +namespace EasyAbp.Abp.WeChat.Common.RequestHandling.Dtos; public class XmlResponseToWeChatModel : IResponseToWeChatModel { diff --git a/src/Common/EasyAbp.Abp.WeChat.Common/RequestHandling/WeChatEventRequestHandlingServiceBase.cs b/src/Common/EasyAbp.Abp.WeChat.Common/RequestHandling/WeChatEventRequestHandlingServiceBase.cs new file mode 100644 index 0000000..e13cbff --- /dev/null +++ b/src/Common/EasyAbp.Abp.WeChat.Common/RequestHandling/WeChatEventRequestHandlingServiceBase.cs @@ -0,0 +1,30 @@ +using System.Threading.Tasks; +using EasyAbp.Abp.WeChat.Common.Infrastructure.Encryption; +using EasyAbp.Abp.WeChat.Common.Infrastructure.Options; +using EasyAbp.Abp.WeChat.Common.RequestHandling.Dtos; +using Volo.Abp.ObjectExtending; + +namespace EasyAbp.Abp.WeChat.Common.RequestHandling; + +public class WeChatEventRequestHandlingServiceBase where TOptions : IAbpWeChatOptions +{ + protected IWeChatNotificationEncryptor WeChatNotificationEncryptor { get; } + + public WeChatEventRequestHandlingServiceBase(IWeChatNotificationEncryptor weChatNotificationEncryptor) + { + WeChatNotificationEncryptor = weChatNotificationEncryptor; + } + + protected virtual async Task DecryptMsgAsync(TOptions options, + WeChatEventRequestModel request) where T : ExtensibleObject, new() + { + return await WeChatNotificationEncryptor.DecryptAsync( + options.Token, + options.EncodingAesKey, + options.AppId, + request.MsgSignature, + request.Timestamp, + request.Nonce, + request.PostData); + } +} \ No newline at end of file diff --git a/src/Official/EasyAbp.Abp.WeChat.Official.Abstractions/EasyAbp.Abp.WeChat.Official.Abstractions.csproj b/src/Official/EasyAbp.Abp.WeChat.Official.Abstractions/EasyAbp.Abp.WeChat.Official.Abstractions.csproj index 4597458..3cb73d1 100644 --- a/src/Official/EasyAbp.Abp.WeChat.Official.Abstractions/EasyAbp.Abp.WeChat.Official.Abstractions.csproj +++ b/src/Official/EasyAbp.Abp.WeChat.Official.Abstractions/EasyAbp.Abp.WeChat.Official.Abstractions.csproj @@ -4,7 +4,7 @@ netstandard2.0 - EasyAbp.Abp.WeChat.OpenPlatform + EasyAbp.Abp.WeChat.Official ABP vNext微信公众号模块,提供对微信公众号业务的支持。 diff --git a/src/Official/EasyAbp.Abp.WeChat.Official.Abstractions/RequestHandling/GetAccessTokenByCodeResult.cs b/src/Official/EasyAbp.Abp.WeChat.Official.Abstractions/RequestHandling/GetAccessTokenByCodeResult.cs index f51f6d0..22ba34c 100644 --- a/src/Official/EasyAbp.Abp.WeChat.Official.Abstractions/RequestHandling/GetAccessTokenByCodeResult.cs +++ b/src/Official/EasyAbp.Abp.WeChat.Official.Abstractions/RequestHandling/GetAccessTokenByCodeResult.cs @@ -1,6 +1,6 @@ using EasyAbp.Abp.WeChat.Common.RequestHandling; -namespace EasyAbp.Abp.WeChat.OpenPlatform.RequestHandling; +namespace EasyAbp.Abp.WeChat.Official.RequestHandling; public class GetAccessTokenByCodeResult : WeChatRequestHandlingResult { diff --git a/src/Official/EasyAbp.Abp.WeChat.Official.Abstractions/RequestHandling/GetJsSdkConfigParametersResult.cs b/src/Official/EasyAbp.Abp.WeChat.Official.Abstractions/RequestHandling/GetJsSdkConfigParametersResult.cs index 8665bae..3d9f463 100644 --- a/src/Official/EasyAbp.Abp.WeChat.Official.Abstractions/RequestHandling/GetJsSdkConfigParametersResult.cs +++ b/src/Official/EasyAbp.Abp.WeChat.Official.Abstractions/RequestHandling/GetJsSdkConfigParametersResult.cs @@ -1,6 +1,6 @@ using EasyAbp.Abp.WeChat.Common.RequestHandling; -namespace EasyAbp.Abp.WeChat.OpenPlatform.RequestHandling; +namespace EasyAbp.Abp.WeChat.Official.RequestHandling; public class GetJsSdkConfigParametersResult : WeChatRequestHandlingResult { diff --git a/src/Official/EasyAbp.Abp.WeChat.Official.Abstractions/RequestHandling/IWeChatOfficialClientRequestHandlingService.cs b/src/Official/EasyAbp.Abp.WeChat.Official.Abstractions/RequestHandling/IWeChatOfficialClientRequestHandlingService.cs index 570c7ae..1f1dd52 100644 --- a/src/Official/EasyAbp.Abp.WeChat.Official.Abstractions/RequestHandling/IWeChatOfficialClientRequestHandlingService.cs +++ b/src/Official/EasyAbp.Abp.WeChat.Official.Abstractions/RequestHandling/IWeChatOfficialClientRequestHandlingService.cs @@ -1,7 +1,7 @@ using System.Threading.Tasks; using JetBrains.Annotations; -namespace EasyAbp.Abp.WeChat.OpenPlatform.RequestHandling; +namespace EasyAbp.Abp.WeChat.Official.RequestHandling; public interface IWeChatOfficialClientRequestHandlingService { diff --git a/src/Official/EasyAbp.Abp.WeChat.Official.Abstractions/RequestHandling/IWeChatOfficialEventRequestHandlingService.cs b/src/Official/EasyAbp.Abp.WeChat.Official.Abstractions/RequestHandling/IWeChatOfficialEventRequestHandlingService.cs index 9d69b1b..84fd6d0 100644 --- a/src/Official/EasyAbp.Abp.WeChat.Official.Abstractions/RequestHandling/IWeChatOfficialEventRequestHandlingService.cs +++ b/src/Official/EasyAbp.Abp.WeChat.Official.Abstractions/RequestHandling/IWeChatOfficialEventRequestHandlingService.cs @@ -1,10 +1,15 @@ -using System.Threading.Tasks; +using System; +using System.Threading.Tasks; +using EasyAbp.Abp.WeChat.Common.RequestHandling.Dtos; using JetBrains.Annotations; -namespace EasyAbp.Abp.WeChat.OpenPlatform.RequestHandling; +namespace EasyAbp.Abp.WeChat.Official.RequestHandling; public interface IWeChatOfficialEventRequestHandlingService { + Task NotifyAsync(WeChatOfficialEventRequestModel input, [CanBeNull] string appId); + + [Obsolete("请使用统一的Notify接口")] Task VerifyAsync(VerifyRequestDto input, [CanBeNull] string appId); Task GetOAuthRedirectUrlAsync( diff --git a/src/Official/EasyAbp.Abp.WeChat.Official.Abstractions/RequestHandling/RedirectUrlRequest.cs b/src/Official/EasyAbp.Abp.WeChat.Official.Abstractions/RequestHandling/RedirectUrlRequest.cs index f53f8d0..dfbfb4c 100644 --- a/src/Official/EasyAbp.Abp.WeChat.Official.Abstractions/RequestHandling/RedirectUrlRequest.cs +++ b/src/Official/EasyAbp.Abp.WeChat.Official.Abstractions/RequestHandling/RedirectUrlRequest.cs @@ -1,4 +1,4 @@ -namespace EasyAbp.Abp.WeChat.OpenPlatform.RequestHandling +namespace EasyAbp.Abp.WeChat.Official.RequestHandling { public class RedirectUrlRequest { diff --git a/src/Official/EasyAbp.Abp.WeChat.Official.Abstractions/RequestHandling/StringValueWeChatRequestHandlingResult.cs b/src/Official/EasyAbp.Abp.WeChat.Official.Abstractions/RequestHandling/StringValueWeChatRequestHandlingResult.cs index 9c3602f..ee16031 100644 --- a/src/Official/EasyAbp.Abp.WeChat.Official.Abstractions/RequestHandling/StringValueWeChatRequestHandlingResult.cs +++ b/src/Official/EasyAbp.Abp.WeChat.Official.Abstractions/RequestHandling/StringValueWeChatRequestHandlingResult.cs @@ -1,6 +1,6 @@ using EasyAbp.Abp.WeChat.Common.RequestHandling; -namespace EasyAbp.Abp.WeChat.OpenPlatform.RequestHandling; +namespace EasyAbp.Abp.WeChat.Official.RequestHandling; public class StringValueWeChatRequestHandlingResult : WeChatRequestHandlingResult { diff --git a/src/Official/EasyAbp.Abp.WeChat.Official.Abstractions/RequestHandling/VerifyRequestDto.cs b/src/Official/EasyAbp.Abp.WeChat.Official.Abstractions/RequestHandling/VerifyRequestDto.cs index 4be401d..2f68f5b 100644 --- a/src/Official/EasyAbp.Abp.WeChat.Official.Abstractions/RequestHandling/VerifyRequestDto.cs +++ b/src/Official/EasyAbp.Abp.WeChat.Official.Abstractions/RequestHandling/VerifyRequestDto.cs @@ -1,5 +1,8 @@ -namespace EasyAbp.Abp.WeChat.OpenPlatform.RequestHandling +using System; + +namespace EasyAbp.Abp.WeChat.Official.RequestHandling { + [Obsolete("请使用统一的Notify接口")] public class VerifyRequestDto { /// diff --git a/src/Official/EasyAbp.Abp.WeChat.Official.Abstractions/RequestHandling/WeChatOfficialEventRequestModel.cs b/src/Official/EasyAbp.Abp.WeChat.Official.Abstractions/RequestHandling/WeChatOfficialEventRequestModel.cs new file mode 100644 index 0000000..294067d --- /dev/null +++ b/src/Official/EasyAbp.Abp.WeChat.Official.Abstractions/RequestHandling/WeChatOfficialEventRequestModel.cs @@ -0,0 +1,13 @@ +using System; +using EasyAbp.Abp.WeChat.Common.RequestHandling.Dtos; + +namespace EasyAbp.Abp.WeChat.Official.RequestHandling; + +[Serializable] +public class WeChatOfficialEventRequestModel : WeChatEventRequestModel +{ + /// + /// 用于微信公众号验证 + /// + public string EchoStr { get; set; } +} \ No newline at end of file diff --git a/src/Official/EasyAbp.Abp.WeChat.Official.HttpApi/Controllers/WeChatController.cs b/src/Official/EasyAbp.Abp.WeChat.Official.HttpApi/Controllers/WeChatController.cs index f767994..0a6fb7b 100644 --- a/src/Official/EasyAbp.Abp.WeChat.Official.HttpApi/Controllers/WeChatController.cs +++ b/src/Official/EasyAbp.Abp.WeChat.Official.HttpApi/Controllers/WeChatController.cs @@ -1,9 +1,15 @@ using System; +using System.IO; +using System.Linq; +using System.Text; using System.Threading.Tasks; using EasyAbp.Abp.WeChat.Common; -using EasyAbp.Abp.WeChat.OpenPlatform.RequestHandling; +using EasyAbp.Abp.WeChat.Common.RequestHandling.Dtos; +using EasyAbp.Abp.WeChat.Official.RequestHandling; using JetBrains.Annotations; +using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; +using Microsoft.Net.Http.Headers; using Volo.Abp; using Volo.Abp.AspNetCore.Mvc; @@ -26,6 +32,7 @@ public WeChatController( _clientRequestHandlingService = clientRequestHandlingService; } + [Obsolete("请使用统一的Notify接口")] [HttpGet] [Route("verify")] public virtual async Task VerifyAsync( @@ -42,6 +49,7 @@ public virtual async Task VerifyAsync( /// 本方法是为了避免多 Route 导致 ABP ApiDescription 报 Warning。 /// 见 /// + [Obsolete("请使用统一的Notify接口")] [HttpGet] [Route("verify/tenant-id/{tenantId}")] public virtual Task Verify2Async( @@ -54,6 +62,7 @@ public virtual Task Verify2Async( /// 本方法是为了避免多 Route 导致 ABP ApiDescription 报 Warning。 /// 见 /// + [Obsolete("请使用统一的Notify接口")] [HttpGet] [Route("verify/app-id/{appId}")] public virtual Task Verify3Async( @@ -66,6 +75,7 @@ public virtual Task Verify3Async( /// 本方法是为了避免多 Route 导致 ABP ApiDescription 报 Warning。 /// 见 /// + [Obsolete("请使用统一的Notify接口")] [HttpGet] [Route("verify/tenant-id/{tenantId}/app-id/{appId}")] public virtual Task Verify4Async( @@ -169,5 +179,94 @@ public virtual async Task GetJsSdkConfigParametersAsync( jsapi_ticket = result.Ticket }); } + + /// + /// 微信应用事件通知接口,开发人员需要实现 处理器来处理回调请求。 + /// + [HttpPost] + [Route("notify")] + public virtual async Task NotifyAsync([CanBeNull] string tenantId, [CanBeNull] string appId) + { + using var changeTenant = CurrentTenant.Change(tenantId.IsNullOrWhiteSpace() ? null : Guid.Parse(tenantId!)); + + var result = await _eventRequestHandlingService.NotifyAsync(await CreateRequestModelAsync(), appId); + + if (!result.Success) + { + return BadRequest(); + } + + var contentType = new MediaTypeHeaderValue(result.ResponseToWeChatModel switch + { + JsonResponseToWeChatModel => "application/json", + XmlResponseToWeChatModel => "application/xml", + null => "text/plain", + _ => "text/plain" + }) + { + Charset = Encoding.UTF8.WebName + }; + + return new ContentResult + { + ContentType = contentType.ToString(), + Content = result.ResponseToWeChatModel?.Content ?? "success", + StatusCode = 200 + }; + } + + /// + /// 本方法是为了避免多 Route 导致 ABP ApiDescription 报 Warning。 + /// 见 + /// + [HttpPost] + [Route("notify/tenant-id/{tenantId}")] + public virtual Task Notify2Async([CanBeNull] string tenantId, [NotNull] string appId) + { + return NotifyAsync(tenantId, appId); + } + + /// + /// 本方法是为了避免多 Route 导致 ABP ApiDescription 报 Warning。 + /// 见 + /// + [HttpPost] + [Route("notify/app-id/{appId}")] + public virtual Task Notify3Async([CanBeNull] string tenantId, [NotNull] string appId) + { + return NotifyAsync(tenantId, appId); + } + + /// + /// 本方法是为了避免多 Route 导致 ABP ApiDescription 报 Warning。 + /// 见 + /// + [HttpPost] + [Route("notify/tenant-id/{tenantId}/app-id/{appId}")] + public virtual Task Notify4Async([CanBeNull] string tenantId, [NotNull] string appId) + { + return NotifyAsync(tenantId, appId); + } + + protected virtual async Task CreateRequestModelAsync() + { + Request.EnableBuffering(); + + using var streamReader = new StreamReader(Request.Body); + + var postData = await streamReader.ReadToEndAsync(); + + Request.Body.Position = 0; + + return new WeChatOfficialEventRequestModel + { + PostData = postData, + MsgSignature = Request.Query["msg_signature"].FirstOrDefault() ?? + Request.Query["signature"].FirstOrDefault(), + Timestamp = Request.Query["timestamp"].FirstOrDefault(), + Nonce = Request.Query["nonce"].FirstOrDefault(), + EchoStr = Request.Query["echostr"].FirstOrDefault() + }; + } } } \ No newline at end of file diff --git a/src/Official/EasyAbp.Abp.WeChat.Official/RequestHandling/IWeChatOfficialAppEventHandler.cs b/src/Official/EasyAbp.Abp.WeChat.Official/RequestHandling/IWeChatOfficialAppEventHandler.cs new file mode 100644 index 0000000..19596a0 --- /dev/null +++ b/src/Official/EasyAbp.Abp.WeChat.Official/RequestHandling/IWeChatOfficialAppEventHandler.cs @@ -0,0 +1,27 @@ +using System.Threading.Tasks; +using EasyAbp.Abp.WeChat.Common.Models; +using EasyAbp.Abp.WeChat.Common.RequestHandling.Dtos; +using JetBrains.Annotations; + +namespace EasyAbp.Abp.WeChat.Official.RequestHandling; + +/// +/// 微信公众号事件通知处理者 +/// +public interface IWeChatOfficialAppEventHandler +{ + /// + /// 仅处理回调请求中,相应的 MsgType 值的事件 + /// + public string MsgType { get; } + + /// + /// Handler 执行的优先级,值更大的先执行 + /// + public int Priority { get; } + + /// + /// 事件处理实现。 + /// + Task HandleAsync([NotNull] string appId, WeChatAppEventModel model); +} \ No newline at end of file diff --git a/src/Official/EasyAbp.Abp.WeChat.Official/RequestHandling/IWeChatOfficialAppEventHandlerResolver.cs b/src/Official/EasyAbp.Abp.WeChat.Official/RequestHandling/IWeChatOfficialAppEventHandlerResolver.cs new file mode 100644 index 0000000..5f8f0f0 --- /dev/null +++ b/src/Official/EasyAbp.Abp.WeChat.Official/RequestHandling/IWeChatOfficialAppEventHandlerResolver.cs @@ -0,0 +1,10 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using JetBrains.Annotations; + +namespace EasyAbp.Abp.WeChat.Official.RequestHandling; + +public interface IWeChatOfficialAppEventHandlerResolver +{ + Task> GetAppEventHandlersAsync([CanBeNull] string msgType); +} \ No newline at end of file diff --git a/src/Official/EasyAbp.Abp.WeChat.Official/RequestHandling/WeChatOfficialAppEventHandlerResolver.cs b/src/Official/EasyAbp.Abp.WeChat.Official/RequestHandling/WeChatOfficialAppEventHandlerResolver.cs new file mode 100644 index 0000000..45568c4 --- /dev/null +++ b/src/Official/EasyAbp.Abp.WeChat.Official/RequestHandling/WeChatOfficialAppEventHandlerResolver.cs @@ -0,0 +1,59 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.DependencyInjection; + +namespace EasyAbp.Abp.WeChat.Official.RequestHandling; + +public class WeChatOfficialAppEventHandlerResolver : IWeChatOfficialAppEventHandlerResolver, ITransientDependency +{ + protected static Dictionary> AppEventHandlerCachedTypes { get; set; } + + private static readonly object SyncObj = new(); + + protected IServiceProvider ServiceProvider { get; } + + public WeChatOfficialAppEventHandlerResolver(IServiceProvider serviceProvider) + { + ServiceProvider = serviceProvider; + } + + public virtual Task> GetAppEventHandlersAsync(string msgType) + { + return ResolveAppEventHandlersAsync(msgType); + } + + protected virtual async Task> ResolveAppEventHandlersAsync( + string msgType) + { + if (AppEventHandlerCachedTypes is null) + { + lock (SyncObj) + { + if (AppEventHandlerCachedTypes is null) + { + var objs = ServiceProvider.GetServices().ToArray(); + + var cacheTypes = objs.GroupBy(obj => obj.MsgType) + .ToDictionary(x => x.Key, x => x.Select(y => y.GetType()).ToList()); + + AppEventHandlerCachedTypes = cacheTypes; + + return objs.Where(x => x.MsgType == msgType).ToList(); + } + } + } + + return AppEventHandlerCachedTypes.TryGetValue(msgType, out var type) + ? await CreateObjectsAsync(type) + : new List(); + } + + protected virtual Task> CreateObjectsAsync(IEnumerable types) + { + return Task.FromResult(types.Select(type => ServiceProvider.GetService(type)).Where(x => x != null) + .Select(x => (TObj)x).ToList()); + } +} \ No newline at end of file diff --git a/src/Official/EasyAbp.Abp.WeChat.Official/RequestHandling/WeChatOfficialClientRequestHandlingService.cs b/src/Official/EasyAbp.Abp.WeChat.Official/RequestHandling/WeChatOfficialClientRequestHandlingService.cs index 767e415..b42b876 100644 --- a/src/Official/EasyAbp.Abp.WeChat.Official/RequestHandling/WeChatOfficialClientRequestHandlingService.cs +++ b/src/Official/EasyAbp.Abp.WeChat.Official/RequestHandling/WeChatOfficialClientRequestHandlingService.cs @@ -9,7 +9,6 @@ using EasyAbp.Abp.WeChat.Official.JsTickets; using EasyAbp.Abp.WeChat.Official.Options; using EasyAbp.Abp.WeChat.Official.Services.Login; -using EasyAbp.Abp.WeChat.OpenPlatform.RequestHandling; using Volo.Abp.DependencyInjection; namespace EasyAbp.Abp.WeChat.Official.RequestHandling; diff --git a/src/Official/EasyAbp.Abp.WeChat.Official/RequestHandling/WeChatOfficialEventRequestHandlingService.cs b/src/Official/EasyAbp.Abp.WeChat.Official/RequestHandling/WeChatOfficialEventRequestHandlingService.cs index 90deb50..ae9cfa7 100644 --- a/src/Official/EasyAbp.Abp.WeChat.Official/RequestHandling/WeChatOfficialEventRequestHandlingService.cs +++ b/src/Official/EasyAbp.Abp.WeChat.Official/RequestHandling/WeChatOfficialEventRequestHandlingService.cs @@ -1,31 +1,84 @@ +using System; +using System.Linq; using System.Threading.Tasks; +using EasyAbp.Abp.WeChat.Common.Infrastructure.Encryption; using EasyAbp.Abp.WeChat.Common.Infrastructure.Options; using EasyAbp.Abp.WeChat.Common.Infrastructure.Signature; +using EasyAbp.Abp.WeChat.Common.Models; +using EasyAbp.Abp.WeChat.Common.RequestHandling; +using EasyAbp.Abp.WeChat.Common.RequestHandling.Dtos; using EasyAbp.Abp.WeChat.Official.Options; -using EasyAbp.Abp.WeChat.OpenPlatform.RequestHandling; using Volo.Abp.DependencyInjection; namespace EasyAbp.Abp.WeChat.Official.RequestHandling; -public class WeChatOfficialEventRequestHandlingService : IWeChatOfficialEventRequestHandlingService, - ITransientDependency +public class WeChatOfficialEventRequestHandlingService : + WeChatEventRequestHandlingServiceBase, + IWeChatOfficialEventRequestHandlingService, ITransientDependency { private readonly ISignatureChecker _signatureChecker; private readonly IAbpWeChatOptionsProvider _optionsProvider; + private readonly IWeChatOfficialAppEventHandlerResolver _weChatOfficialAppEventHandlerResolver; public WeChatOfficialEventRequestHandlingService( ISignatureChecker signatureChecker, - IAbpWeChatOptionsProvider optionsProvider) + IAbpWeChatOptionsProvider optionsProvider, + IWeChatOfficialAppEventHandlerResolver weChatOfficialAppEventHandlerResolver, + IWeChatNotificationEncryptor weChatNotificationEncryptor) : base(weChatNotificationEncryptor) { _signatureChecker = signatureChecker; _optionsProvider = optionsProvider; + _weChatOfficialAppEventHandlerResolver = weChatOfficialAppEventHandlerResolver; } + /// + /// 微信应用事件通知接口,开发人员需要实现 处理器来处理回调请求。 + /// + public virtual async Task NotifyAsync(WeChatOfficialEventRequestModel input, string appId) + { + var options = await _optionsProvider.GetAsync(appId); + + if (!input.EchoStr.IsNullOrWhiteSpace()) + { + if (await ValidateSignatureAsync(options.Token, input.Timestamp, input.Nonce, input.MsgSignature)) + { + return new AppEventHandlingResult(new PlainTextResponseToWeChatModel { Content = input.EchoStr }); + } + + return new AppEventHandlingResult(new PlainTextResponseToWeChatModel { Content = "非法参数。" }); + } + + var model = await DecryptMsgAsync(options, input); + + IResponseToWeChatModel responseToWeChatModel = null; + + foreach (var handler in (await _weChatOfficialAppEventHandlerResolver.GetAppEventHandlersAsync(model.MsgType)) + .OrderByDescending(x => x.Priority)) + { + var result = await handler.HandleAsync(options.AppId, model); + + if (result.ResponseToWeChatModel != null) + { + responseToWeChatModel = result.ResponseToWeChatModel; + } + + if (!result.Success) + { + return result; + } + } + + return responseToWeChatModel is null + ? new AppEventHandlingResult(true) + : new AppEventHandlingResult(responseToWeChatModel); + } + + [Obsolete("请使用统一的Notify接口")] public virtual async Task VerifyAsync(VerifyRequestDto input, string appId) { var options = await _optionsProvider.GetAsync(appId); - if (_signatureChecker.Validate(options.Token, input.Timestamp, input.Nonce, input.Signature)) + if (await ValidateSignatureAsync(options.Token, input.Timestamp, input.Nonce, input.Signature)) { return new StringValueWeChatRequestHandlingResult(true, input.EchoStr); } @@ -33,6 +86,11 @@ public virtual async Task VerifyAsync(Ve return new StringValueWeChatRequestHandlingResult(false, null, "非法参数。"); } + protected virtual Task ValidateSignatureAsync(string token, string timestamp, string nonce, string signature) + { + return Task.FromResult(_signatureChecker.Validate(token, timestamp, nonce, signature)); + } + public virtual async Task GetOAuthRedirectUrlAsync( RedirectUrlRequest input, string appId) { diff --git a/src/OpenPlatform/EasyAbp.Abp.WeChat.OpenPlatform.Abstractions/RequestHandling/IWeChatThirdPartyPlatformEventRequestHandlingService.cs b/src/OpenPlatform/EasyAbp.Abp.WeChat.OpenPlatform.Abstractions/RequestHandling/IWeChatThirdPartyPlatformEventRequestHandlingService.cs index c2e8c14..48fbb11 100644 --- a/src/OpenPlatform/EasyAbp.Abp.WeChat.OpenPlatform.Abstractions/RequestHandling/IWeChatThirdPartyPlatformEventRequestHandlingService.cs +++ b/src/OpenPlatform/EasyAbp.Abp.WeChat.OpenPlatform.Abstractions/RequestHandling/IWeChatThirdPartyPlatformEventRequestHandlingService.cs @@ -1,5 +1,6 @@ using System.Threading.Tasks; using EasyAbp.Abp.WeChat.Common.RequestHandling; +using EasyAbp.Abp.WeChat.Common.RequestHandling.Dtos; using EasyAbp.Abp.WeChat.OpenPlatform.RequestHandling.Dtos; namespace EasyAbp.Abp.WeChat.OpenPlatform.RequestHandling; diff --git a/src/OpenPlatform/EasyAbp.Abp.WeChat.OpenPlatform.HttpApi/Controllers/WeChatThirdPartyPlatformController.cs b/src/OpenPlatform/EasyAbp.Abp.WeChat.OpenPlatform.HttpApi/Controllers/WeChatThirdPartyPlatformController.cs index daefc6f..c370327 100644 --- a/src/OpenPlatform/EasyAbp.Abp.WeChat.OpenPlatform.HttpApi/Controllers/WeChatThirdPartyPlatformController.cs +++ b/src/OpenPlatform/EasyAbp.Abp.WeChat.OpenPlatform.HttpApi/Controllers/WeChatThirdPartyPlatformController.cs @@ -115,6 +115,7 @@ await _requestHandlingService.NotifyAppAsync(new NotifyAppInput { JsonResponseToWeChatModel => "application/json", XmlResponseToWeChatModel => "application/xml", + PlainTextResponseToWeChatModel => "text/plain", null => "text/plain", _ => "text/plain" }) @@ -181,7 +182,7 @@ protected virtual async Task CreateRequestModelAsync() PostData = postData, MsgSignature = Request.Query["msg_signature"].FirstOrDefault(), Timestamp = Request.Query["timestamp"].FirstOrDefault(), - Notice = Request.Query["nonce"].FirstOrDefault() + Nonce = Request.Query["nonce"].FirstOrDefault() }; } } \ No newline at end of file diff --git a/src/OpenPlatform/EasyAbp.Abp.WeChat.OpenPlatform/ThirdPartyPlatform/RequestHandling/IWeChatThirdPartyPlatformAppEventHandler.cs b/src/OpenPlatform/EasyAbp.Abp.WeChat.OpenPlatform/ThirdPartyPlatform/RequestHandling/IWeChatThirdPartyPlatformAppEventHandler.cs index fe28df7..93641a9 100644 --- a/src/OpenPlatform/EasyAbp.Abp.WeChat.OpenPlatform/ThirdPartyPlatform/RequestHandling/IWeChatThirdPartyPlatformAppEventHandler.cs +++ b/src/OpenPlatform/EasyAbp.Abp.WeChat.OpenPlatform/ThirdPartyPlatform/RequestHandling/IWeChatThirdPartyPlatformAppEventHandler.cs @@ -1,6 +1,6 @@ using System.Threading.Tasks; using EasyAbp.Abp.WeChat.Common.Models; -using EasyAbp.Abp.WeChat.OpenPlatform.RequestHandling.Dtos; +using EasyAbp.Abp.WeChat.Common.RequestHandling.Dtos; using JetBrains.Annotations; namespace EasyAbp.Abp.WeChat.OpenPlatform.ThirdPartyPlatform.RequestHandling; diff --git a/src/OpenPlatform/EasyAbp.Abp.WeChat.OpenPlatform/ThirdPartyPlatform/RequestHandling/IThirdPartyPlatformEventHandlerResolver.cs b/src/OpenPlatform/EasyAbp.Abp.WeChat.OpenPlatform/ThirdPartyPlatform/RequestHandling/IWeChatThirdPartyPlatformEventHandlerResolver.cs similarity index 86% rename from src/OpenPlatform/EasyAbp.Abp.WeChat.OpenPlatform/ThirdPartyPlatform/RequestHandling/IThirdPartyPlatformEventHandlerResolver.cs rename to src/OpenPlatform/EasyAbp.Abp.WeChat.OpenPlatform/ThirdPartyPlatform/RequestHandling/IWeChatThirdPartyPlatformEventHandlerResolver.cs index bc63e5a..b79a8db 100644 --- a/src/OpenPlatform/EasyAbp.Abp.WeChat.OpenPlatform/ThirdPartyPlatform/RequestHandling/IThirdPartyPlatformEventHandlerResolver.cs +++ b/src/OpenPlatform/EasyAbp.Abp.WeChat.OpenPlatform/ThirdPartyPlatform/RequestHandling/IWeChatThirdPartyPlatformEventHandlerResolver.cs @@ -4,7 +4,7 @@ namespace EasyAbp.Abp.WeChat.OpenPlatform.ThirdPartyPlatform.RequestHandling; -public interface IThirdPartyPlatformEventHandlerResolver +public interface IWeChatThirdPartyPlatformEventHandlerResolver { Task> GetAuthEventHandlersAsync([CanBeNull] string infoType); diff --git a/src/OpenPlatform/EasyAbp.Abp.WeChat.OpenPlatform/ThirdPartyPlatform/RequestHandling/ReleaseTestWeChatThirdPartyPlatformAppEventHandler.cs b/src/OpenPlatform/EasyAbp.Abp.WeChat.OpenPlatform/ThirdPartyPlatform/RequestHandling/ReleaseTestWeChatThirdPartyPlatformAppEventHandler.cs index 63382ea..23f437e 100644 --- a/src/OpenPlatform/EasyAbp.Abp.WeChat.OpenPlatform/ThirdPartyPlatform/RequestHandling/ReleaseTestWeChatThirdPartyPlatformAppEventHandler.cs +++ b/src/OpenPlatform/EasyAbp.Abp.WeChat.OpenPlatform/ThirdPartyPlatform/RequestHandling/ReleaseTestWeChatThirdPartyPlatformAppEventHandler.cs @@ -6,6 +6,7 @@ using EasyAbp.Abp.WeChat.Common.Infrastructure.Options; using EasyAbp.Abp.WeChat.Common.Infrastructure.Services; using EasyAbp.Abp.WeChat.Common.Models; +using EasyAbp.Abp.WeChat.Common.RequestHandling.Dtos; using EasyAbp.Abp.WeChat.OpenPlatform.RequestHandling.Dtos; using EasyAbp.Abp.WeChat.OpenPlatform.ThirdPartyPlatform.Options; using EasyAbp.Abp.WeChat.OpenPlatform.ThirdPartyPlatform.Services; diff --git a/src/OpenPlatform/EasyAbp.Abp.WeChat.OpenPlatform/ThirdPartyPlatform/RequestHandling/ThirdPartyPlatformEventHandlerResolver.cs b/src/OpenPlatform/EasyAbp.Abp.WeChat.OpenPlatform/ThirdPartyPlatform/RequestHandling/WeChatThirdPartyPlatformEventHandlerResolver.cs similarity index 90% rename from src/OpenPlatform/EasyAbp.Abp.WeChat.OpenPlatform/ThirdPartyPlatform/RequestHandling/ThirdPartyPlatformEventHandlerResolver.cs rename to src/OpenPlatform/EasyAbp.Abp.WeChat.OpenPlatform/ThirdPartyPlatform/RequestHandling/WeChatThirdPartyPlatformEventHandlerResolver.cs index 0e54386..216ddb5 100644 --- a/src/OpenPlatform/EasyAbp.Abp.WeChat.OpenPlatform/ThirdPartyPlatform/RequestHandling/ThirdPartyPlatformEventHandlerResolver.cs +++ b/src/OpenPlatform/EasyAbp.Abp.WeChat.OpenPlatform/ThirdPartyPlatform/RequestHandling/WeChatThirdPartyPlatformEventHandlerResolver.cs @@ -7,7 +7,8 @@ namespace EasyAbp.Abp.WeChat.OpenPlatform.ThirdPartyPlatform.RequestHandling; -public class ThirdPartyPlatformEventHandlerResolver : IThirdPartyPlatformEventHandlerResolver, ITransientDependency +public class WeChatThirdPartyPlatformEventHandlerResolver : IWeChatThirdPartyPlatformEventHandlerResolver, + ITransientDependency { protected static Dictionary> AuthEventHandlerCachedTypes { get; set; } protected static Dictionary> AppEventHandlerCachedTypes { get; set; } @@ -17,7 +18,7 @@ public class ThirdPartyPlatformEventHandlerResolver : IThirdPartyPlatformEventHa protected IServiceProvider ServiceProvider { get; } - public ThirdPartyPlatformEventHandlerResolver(IServiceProvider serviceProvider) + public WeChatThirdPartyPlatformEventHandlerResolver(IServiceProvider serviceProvider) { ServiceProvider = serviceProvider; } @@ -54,8 +55,8 @@ protected virtual async Task> Re } } - return AuthEventHandlerCachedTypes.ContainsKey(infoType) - ? await CreateObjectsAsync(AuthEventHandlerCachedTypes[infoType]) + return AuthEventHandlerCachedTypes.TryGetValue(infoType, out var type) + ? await CreateObjectsAsync(type) : new List(); } diff --git a/src/OpenPlatform/EasyAbp.Abp.WeChat.OpenPlatform/ThirdPartyPlatform/RequestHandling/WeChatThirdPartyPlatformEventRequestHandlingService.cs b/src/OpenPlatform/EasyAbp.Abp.WeChat.OpenPlatform/ThirdPartyPlatform/RequestHandling/WeChatThirdPartyPlatformEventRequestHandlingService.cs index 5cc6da4..7849392 100644 --- a/src/OpenPlatform/EasyAbp.Abp.WeChat.OpenPlatform/ThirdPartyPlatform/RequestHandling/WeChatThirdPartyPlatformEventRequestHandlingService.cs +++ b/src/OpenPlatform/EasyAbp.Abp.WeChat.OpenPlatform/ThirdPartyPlatform/RequestHandling/WeChatThirdPartyPlatformEventRequestHandlingService.cs @@ -10,28 +10,26 @@ using EasyAbp.Abp.WeChat.OpenPlatform.ThirdPartyPlatform.Models; using EasyAbp.Abp.WeChat.OpenPlatform.ThirdPartyPlatform.Options; using Volo.Abp.DependencyInjection; -using Volo.Abp.ObjectExtending; namespace EasyAbp.Abp.WeChat.OpenPlatform.ThirdPartyPlatform.RequestHandling; public class WeChatThirdPartyPlatformEventRequestHandlingService : + WeChatEventRequestHandlingServiceBase, IWeChatThirdPartyPlatformEventRequestHandlingService, ITransientDependency { - private readonly IThirdPartyPlatformEventHandlerResolver _thirdPartyPlatformEventHandlerResolver; + private readonly IWeChatThirdPartyPlatformEventHandlerResolver _weChatThirdPartyPlatformEventHandlerResolver; private readonly ICurrentWeChatThirdPartyPlatform _currentWeChatThirdPartyPlatform; private readonly IAbpWeChatOptionsProvider _optionsProvider; - private readonly IWeChatNotificationEncryptor _weChatNotificationEncryptor; public WeChatThirdPartyPlatformEventRequestHandlingService( - IThirdPartyPlatformEventHandlerResolver thirdPartyPlatformEventHandlerResolver, + IWeChatThirdPartyPlatformEventHandlerResolver weChatThirdPartyPlatformEventHandlerResolver, ICurrentWeChatThirdPartyPlatform currentWeChatThirdPartyPlatform, IAbpWeChatOptionsProvider optionsProvider, - IWeChatNotificationEncryptor weChatNotificationEncryptor) + IWeChatNotificationEncryptor weChatNotificationEncryptor) : base(weChatNotificationEncryptor) { - _thirdPartyPlatformEventHandlerResolver = thirdPartyPlatformEventHandlerResolver; + _weChatThirdPartyPlatformEventHandlerResolver = weChatThirdPartyPlatformEventHandlerResolver; _currentWeChatThirdPartyPlatform = currentWeChatThirdPartyPlatform; _optionsProvider = optionsProvider; - _weChatNotificationEncryptor = weChatNotificationEncryptor; } /// @@ -45,7 +43,8 @@ public virtual async Task NotifyAuthAsync(NotifyAut var model = await DecryptMsgAsync(options, input.EventRequest); - foreach (var handler in await _thirdPartyPlatformEventHandlerResolver.GetAuthEventHandlersAsync(model.InfoType)) + foreach (var handler in await _weChatThirdPartyPlatformEventHandlerResolver.GetAuthEventHandlersAsync( + model.InfoType)) { var result = await handler.HandleAsync(model); @@ -72,7 +71,8 @@ public virtual async Task NotifyAppAsync(NotifyAppInput IResponseToWeChatModel responseToWeChatModel = null; - foreach (var handler in (await _thirdPartyPlatformEventHandlerResolver.GetAppEventHandlersAsync(model.MsgType)) + foreach (var handler in (await _weChatThirdPartyPlatformEventHandlerResolver.GetAppEventHandlersAsync( + model.MsgType)) .OrderByDescending(x => x.Priority)) { var result = await handler.HandleAsync(options.AppId, input.AuthorizerAppId, model); @@ -92,17 +92,4 @@ public virtual async Task NotifyAppAsync(NotifyAppInput ? new AppEventHandlingResult(true) : new AppEventHandlingResult(responseToWeChatModel); } - - protected virtual async Task DecryptMsgAsync(AbpWeChatThirdPartyPlatformOptions options, - WeChatEventRequestModel request) where T : ExtensibleObject, new() - { - return await _weChatNotificationEncryptor.DecryptAsync( - options.Token, - options.EncodingAesKey, - options.AppId, - request.MsgSignature, - request.Timestamp, - request.Notice, - request.PostData); - } } \ No newline at end of file diff --git a/tests/EasyAbp.Abp.WeChat.Common.Tests/AbpWeChatCommonTestsConsts.cs b/tests/EasyAbp.Abp.WeChat.Common.Tests/AbpWeChatCommonTestsConsts.cs new file mode 100644 index 0000000..4334330 --- /dev/null +++ b/tests/EasyAbp.Abp.WeChat.Common.Tests/AbpWeChatCommonTestsConsts.cs @@ -0,0 +1,13 @@ +namespace EasyAbp.Abp.WeChat.Common.Tests; + +public class AbpWeChatCommonTestsConsts +{ + public const string AppId = "wx5823bf96d3bd56c7"; + public const string AppSecret = "123456"; + public const string Token = "QDG6eK"; + public const string EncodingAesKey = "jWmYm7qr5nMoAUwZRjGtBxmz3KA1tkAj3ykkR6q2B2C"; + public const string ReqMsgSig = "477715d11cdb4164915debcba66cb864d751f3e6"; + public const string ReqTimeStamp = "1409659813"; + public const string ReqNonce = "1372623149"; + public const string ReqData = ""; +} \ No newline at end of file diff --git a/tests/EasyAbp.Abp.WeChat.Common.Tests/Encryptors/TestAbpWeChatOptions.cs b/tests/EasyAbp.Abp.WeChat.Common.Tests/Encryptors/TestAbpWeChatOptions.cs new file mode 100644 index 0000000..af1b1d1 --- /dev/null +++ b/tests/EasyAbp.Abp.WeChat.Common.Tests/Encryptors/TestAbpWeChatOptions.cs @@ -0,0 +1,14 @@ +using EasyAbp.Abp.WeChat.Common.Infrastructure.Options; + +namespace EasyAbp.Abp.WeChat.Common.Tests.Encryptors; + +public class TestAbpWeChatOptions : IAbpWeChatOptions +{ + public string AppId { get; set; } + + public string AppSecret { get; set; } + + public string Token { get; set; } + + public string EncodingAesKey { get; set; } +} \ No newline at end of file diff --git a/tests/EasyAbp.Abp.WeChat.OpenPlatform.Tests/ThirdPartyPlatform/WeChatNotificationEncryptorTest.cs b/tests/EasyAbp.Abp.WeChat.Common.Tests/Encryptors/WeChatNotificationEncryptorTest.cs similarity index 59% rename from tests/EasyAbp.Abp.WeChat.OpenPlatform.Tests/ThirdPartyPlatform/WeChatNotificationEncryptorTest.cs rename to tests/EasyAbp.Abp.WeChat.Common.Tests/Encryptors/WeChatNotificationEncryptorTest.cs index 877e1aa..73f75c5 100644 --- a/tests/EasyAbp.Abp.WeChat.OpenPlatform.Tests/ThirdPartyPlatform/WeChatNotificationEncryptorTest.cs +++ b/tests/EasyAbp.Abp.WeChat.Common.Tests/Encryptors/WeChatNotificationEncryptorTest.cs @@ -1,24 +1,23 @@ using System.Threading.Tasks; using EasyAbp.Abp.WeChat.Common.Infrastructure.Encryption; using EasyAbp.Abp.WeChat.Common.Models; -using EasyAbp.Abp.WeChat.OpenPlatform.ThirdPartyPlatform.Options; using Shouldly; using Xunit; -namespace EasyAbp.Abp.WeChat.OpenPlatform.Tests.ThirdPartyPlatform; +namespace EasyAbp.Abp.WeChat.Common.Tests.Encryptors; -public class WeChatNotificationEncryptorTest : AbpWeChatOpenPlatformTestBase +public class WeChatNotificationEncryptorTest : AbpWeChatCommonTestBase { [Fact] public async Task Should_Encrypt_Xml() { var encryptor = GetRequiredService(); - var options = new AbpWeChatThirdPartyPlatformOptions + var options = new TestAbpWeChatOptions { - Token = AbpWeChatOpenPlatformTestsConsts.Token, - AppId = AbpWeChatOpenPlatformTestsConsts.AppId, - EncodingAesKey = AbpWeChatOpenPlatformTestsConsts.EncodingAesKey + Token = AbpWeChatCommonTestsConsts.Token, + AppId = AbpWeChatCommonTestsConsts.AppId, + EncodingAesKey = AbpWeChatCommonTestsConsts.EncodingAesKey }; var encryptedXml = await encryptor.EncryptAsync( @@ -42,21 +41,21 @@ public async Task Should_Decrypt_Xml() { var encryptor = GetRequiredService(); - var options = new AbpWeChatThirdPartyPlatformOptions + var options = new TestAbpWeChatOptions { - Token = AbpWeChatOpenPlatformTestsConsts.Token, - AppId = AbpWeChatOpenPlatformTestsConsts.AppId, - EncodingAesKey = AbpWeChatOpenPlatformTestsConsts.EncodingAesKey + Token = AbpWeChatCommonTestsConsts.Token, + AppId = AbpWeChatCommonTestsConsts.AppId, + EncodingAesKey = AbpWeChatCommonTestsConsts.EncodingAesKey }; var model = await encryptor.DecryptAsync( options.Token, options.EncodingAesKey, options.AppId, - AbpWeChatOpenPlatformTestsConsts.ReqMsgSig, - AbpWeChatOpenPlatformTestsConsts.ReqTimeStamp, - AbpWeChatOpenPlatformTestsConsts.ReqNonce, - AbpWeChatOpenPlatformTestsConsts.ReqData); + AbpWeChatCommonTestsConsts.ReqMsgSig, + AbpWeChatCommonTestsConsts.ReqTimeStamp, + AbpWeChatCommonTestsConsts.ReqNonce, + AbpWeChatCommonTestsConsts.ReqData); model.MsgType.ShouldBe("text"); model.ToUserName.ShouldBe("wx5823bf96d3bd56c7"); diff --git a/tests/EasyAbp.Abp.WeChat.Official.Tests/EventHandling/Fakes/FakeEventWeChatOfficialAppEventHandler.cs b/tests/EasyAbp.Abp.WeChat.Official.Tests/EventHandling/Fakes/FakeEventWeChatOfficialAppEventHandler.cs new file mode 100644 index 0000000..9549d47 --- /dev/null +++ b/tests/EasyAbp.Abp.WeChat.Official.Tests/EventHandling/Fakes/FakeEventWeChatOfficialAppEventHandler.cs @@ -0,0 +1,18 @@ +using System.Threading.Tasks; +using EasyAbp.Abp.WeChat.Common.Models; +using EasyAbp.Abp.WeChat.Common.RequestHandling.Dtos; +using EasyAbp.Abp.WeChat.Official.RequestHandling; +using Volo.Abp.DependencyInjection; + +namespace EasyAbp.Abp.WeChat.Official.Tests.EventHandling.Fakes; + +public class FakeEventWeChatOfficialAppEventHandler : IWeChatOfficialAppEventHandler, ITransientDependency +{ + public string MsgType => "event"; + public int Priority => 0; + + public Task HandleAsync(string appId, WeChatAppEventModel model) + { + return Task.FromResult(new AppEventHandlingResult(true)); + } +} \ No newline at end of file diff --git a/tests/EasyAbp.Abp.WeChat.Official.Tests/EventHandling/Fakes/FakeTextWeChatOfficialAppEventHandler.cs b/tests/EasyAbp.Abp.WeChat.Official.Tests/EventHandling/Fakes/FakeTextWeChatOfficialAppEventHandler.cs new file mode 100644 index 0000000..ad29378 --- /dev/null +++ b/tests/EasyAbp.Abp.WeChat.Official.Tests/EventHandling/Fakes/FakeTextWeChatOfficialAppEventHandler.cs @@ -0,0 +1,19 @@ +using System.Threading.Tasks; +using EasyAbp.Abp.WeChat.Common.Models; +using EasyAbp.Abp.WeChat.Common.RequestHandling.Dtos; +using EasyAbp.Abp.WeChat.Official.RequestHandling; +using Volo.Abp.DependencyInjection; + +namespace EasyAbp.Abp.WeChat.Official.Tests.EventHandling.Fakes; + +public class FakeTextWeChatOfficialAppEventHandler : IWeChatOfficialAppEventHandler, + ITransientDependency +{ + public string MsgType => "text"; + public int Priority => 0; + + public Task HandleAsync(string aAppId, WeChatAppEventModel model) + { + return Task.FromResult(new AppEventHandlingResult(true)); + } +} \ No newline at end of file diff --git a/tests/EasyAbp.Abp.WeChat.Official.Tests/EventHandling/ThirdPartyPlatformEventHandlerResolverTests.cs b/tests/EasyAbp.Abp.WeChat.Official.Tests/EventHandling/ThirdPartyPlatformEventHandlerResolverTests.cs new file mode 100644 index 0000000..1daa053 --- /dev/null +++ b/tests/EasyAbp.Abp.WeChat.Official.Tests/EventHandling/ThirdPartyPlatformEventHandlerResolverTests.cs @@ -0,0 +1,28 @@ +using System.Threading.Tasks; +using EasyAbp.Abp.WeChat.Official.RequestHandling; +using EasyAbp.Abp.WeChat.Official.Tests.EventHandling.Fakes; +using Shouldly; +using Xunit; + +namespace EasyAbp.Abp.WeChat.Official.Tests.EventHandling; + +public class ThirdPartyPlatformEventHandlerResolverTests : AbpWeChatOfficialTestBase +{ + [Fact] + public async Task Should_Resolve_Handlers() + { + var resolver = GetRequiredService(); + + var textHandlers = await resolver.GetAppEventHandlersAsync("text"); + + textHandlers.Count.ShouldBe(1); + textHandlers.ShouldContain(x => + x.GetType() == typeof(FakeTextWeChatOfficialAppEventHandler)); + + var eventHandlers = await resolver.GetAppEventHandlersAsync("event"); + + eventHandlers.Count.ShouldBe(1); + eventHandlers.ShouldContain(x => + x.GetType() == typeof(FakeEventWeChatOfficialAppEventHandler)); + } +} \ No newline at end of file diff --git a/tests/EasyAbp.Abp.WeChat.OpenPlatform.Tests/ThirdPartyPlatform/Fakes/FakeEventWeChatThirdPartyPlatformAppEventHandler.cs b/tests/EasyAbp.Abp.WeChat.OpenPlatform.Tests/ThirdPartyPlatform/Fakes/FakeEventWeChatThirdPartyPlatformAppEventHandler.cs index c57179d..782ef64 100644 --- a/tests/EasyAbp.Abp.WeChat.OpenPlatform.Tests/ThirdPartyPlatform/Fakes/FakeEventWeChatThirdPartyPlatformAppEventHandler.cs +++ b/tests/EasyAbp.Abp.WeChat.OpenPlatform.Tests/ThirdPartyPlatform/Fakes/FakeEventWeChatThirdPartyPlatformAppEventHandler.cs @@ -1,5 +1,6 @@ using System.Threading.Tasks; using EasyAbp.Abp.WeChat.Common.Models; +using EasyAbp.Abp.WeChat.Common.RequestHandling.Dtos; using EasyAbp.Abp.WeChat.OpenPlatform.RequestHandling.Dtos; using EasyAbp.Abp.WeChat.OpenPlatform.ThirdPartyPlatform.RequestHandling; using Volo.Abp.DependencyInjection; diff --git a/tests/EasyAbp.Abp.WeChat.OpenPlatform.Tests/ThirdPartyPlatform/Fakes/FakeTextWeChatThirdPartyPlatformAppEventHandler.cs b/tests/EasyAbp.Abp.WeChat.OpenPlatform.Tests/ThirdPartyPlatform/Fakes/FakeTextWeChatThirdPartyPlatformAppEventHandler.cs index 7d2a465..40d8a15 100644 --- a/tests/EasyAbp.Abp.WeChat.OpenPlatform.Tests/ThirdPartyPlatform/Fakes/FakeTextWeChatThirdPartyPlatformAppEventHandler.cs +++ b/tests/EasyAbp.Abp.WeChat.OpenPlatform.Tests/ThirdPartyPlatform/Fakes/FakeTextWeChatThirdPartyPlatformAppEventHandler.cs @@ -1,5 +1,6 @@ using System.Threading.Tasks; using EasyAbp.Abp.WeChat.Common.Models; +using EasyAbp.Abp.WeChat.Common.RequestHandling.Dtos; using EasyAbp.Abp.WeChat.OpenPlatform.RequestHandling.Dtos; using EasyAbp.Abp.WeChat.OpenPlatform.ThirdPartyPlatform.RequestHandling; using Volo.Abp.DependencyInjection; diff --git a/tests/EasyAbp.Abp.WeChat.OpenPlatform.Tests/ThirdPartyPlatform/ReleaseTestEventHandlingTests.cs b/tests/EasyAbp.Abp.WeChat.OpenPlatform.Tests/ThirdPartyPlatform/ReleaseTestEventHandlingTests.cs index fee5442..e929f24 100644 --- a/tests/EasyAbp.Abp.WeChat.OpenPlatform.Tests/ThirdPartyPlatform/ReleaseTestEventHandlingTests.cs +++ b/tests/EasyAbp.Abp.WeChat.OpenPlatform.Tests/ThirdPartyPlatform/ReleaseTestEventHandlingTests.cs @@ -1,6 +1,7 @@ using System.Linq; using System.Threading.Tasks; using EasyAbp.Abp.WeChat.Common.Models; +using EasyAbp.Abp.WeChat.Common.RequestHandling.Dtos; using EasyAbp.Abp.WeChat.OpenPlatform.RequestHandling.Dtos; using EasyAbp.Abp.WeChat.OpenPlatform.ThirdPartyPlatform.RequestHandling; using Shouldly; diff --git a/tests/EasyAbp.Abp.WeChat.OpenPlatform.Tests/ThirdPartyPlatform/ThirdPartyPlatformEventHandlerResolverTests.cs b/tests/EasyAbp.Abp.WeChat.OpenPlatform.Tests/ThirdPartyPlatform/ThirdPartyPlatformEventHandlerResolverTests.cs index 4e880a3..819e4b4 100644 --- a/tests/EasyAbp.Abp.WeChat.OpenPlatform.Tests/ThirdPartyPlatform/ThirdPartyPlatformEventHandlerResolverTests.cs +++ b/tests/EasyAbp.Abp.WeChat.OpenPlatform.Tests/ThirdPartyPlatform/ThirdPartyPlatformEventHandlerResolverTests.cs @@ -12,7 +12,7 @@ public class ThirdPartyPlatformEventHandlerResolverTests : AbpWeChatOpenPlatform [Fact] public async Task Should_Resolve_Handlers() { - var resolver = GetRequiredService(); + var resolver = GetRequiredService(); var unauthorizedHandlers = await resolver.GetAuthEventHandlersAsync(WeChatThirdPartyPlatformAuthEventInfoTypes.Unauthorized);