Browse Source

Merge pull request #1373 from colinin/refactor-wechat-message-resolver

refactor(wechat): Refactor the wechat message resolver
pull/1377/head
yx lin 3 months ago
committed by GitHub
parent
commit
b830857a4e
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 36
      aspnet-core/framework/wechat/LINGYUN.Abp.Identity.WeChat.Work/LINGYUN/Abp/Identity/WeChat/Work/AbpWeChatWorkClaimsPrincipalContributor.cs
  2. 12
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Common/LINGYUN/Abp/WeChat/Common/Messages/AbpWeChatMessageResolveOptions.cs
  3. 1
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Common/LINGYUN/Abp/WeChat/Common/Messages/IMessageResolveContributor.cs
  4. 7
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Common/LINGYUN/Abp/WeChat/Common/Messages/IMessageResolver.cs
  5. 1
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Common/LINGYUN/Abp/WeChat/Common/Messages/MessageResolveContributorBase.cs
  6. 34
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Common/LINGYUN/Abp/WeChat/Common/Messages/MessageResolverBase.cs
  7. 7
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Official.Application/LINGYUN/Abp/WeChat/Official/Message/WeChatMessageAppService.cs
  8. 3
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Official/LINGYUN/Abp/WeChat/Official/AbpWeChatOfficialModule.cs
  9. 2
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Official/LINGYUN/Abp/WeChat/Official/Messages/AbpWeChatOfficialMessageResolveOptions.cs
  10. 16
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Official/LINGYUN/Abp/WeChat/Official/Messages/IWeChatOfficialMessageResolver.cs
  11. 5
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Official/LINGYUN/Abp/WeChat/Official/Messages/WeChatOfficialEventResolveContributor.cs
  12. 5
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Official/LINGYUN/Abp/WeChat/Official/Messages/WeChatOfficialMessageResolveContributor.cs
  13. 11
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Official/LINGYUN/Abp/WeChat/Official/Messages/WeChatOfficialMessageResolveContributorBase.cs
  14. 39
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Official/LINGYUN/Abp/WeChat/Official/Messages/WeChatOfficialMessageResolver.cs
  15. 7
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.Application/LINGYUN/Abp/WeChat/Work/Message/WeChatWorkMessageAppService.cs
  16. 1
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.Common/LINGYUN.Abp.WeChat.Work.Common.csproj
  17. 5
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.Common/LINGYUN/Abp/WeChat/Work/Common/AbpWeChatWorkCommonModule.cs
  18. 2
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.Common/LINGYUN/Abp/WeChat/Work/Common/Messages/AbpWeChatWorkMessageResolveOptions.cs
  19. 16
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.Common/LINGYUN/Abp/WeChat/Work/Common/Messages/IWeChatWorkMessageResolver.cs
  20. 30
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.Common/LINGYUN/Abp/WeChat/Work/Common/Messages/Models/BookMeetingRoomEvent.cs
  21. 30
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.Common/LINGYUN/Abp/WeChat/Work/Common/Messages/Models/CancelMeetingRoomEvent.cs
  22. 5
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.Common/LINGYUN/Abp/WeChat/Work/Common/Messages/WeChatWorkEventResolveContributor.cs
  23. 5
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.Common/LINGYUN/Abp/WeChat/Work/Common/Messages/WeChatWorkMessageResolveContributor.cs
  24. 12
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.Common/LINGYUN/Abp/WeChat/Work/Common/Messages/WeChatWorkMessageResolveContributorBase.cs
  25. 39
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.Common/LINGYUN/Abp/WeChat/Work/Common/Messages/WeChatWorkMessageResolver.cs
  26. 1
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work/LINGYUN.Abp.WeChat.Work.csproj
  27. 18
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work/LINGYUN/Abp/WeChat/Work/AbpWeChatWorkModule.cs
  28. 7
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work/LINGYUN/Abp/WeChat/Work/WeChatWorkRequest.cs
  29. 61
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work/Microsoft/Extensions/DependencyInjection/IHttpClientFactoryWeChatWorkExtensions.cs

36
aspnet-core/framework/wechat/LINGYUN.Abp.Identity.WeChat.Work/LINGYUN/Abp/Identity/WeChat/Work/AbpWeChatWorkClaimsPrincipalContributor.cs

@ -0,0 +1,36 @@
using LINGYUN.Abp.WeChat.Work.Authorize;
using LINGYUN.Abp.WeChat.Work.Security.Claims;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Linq;
using System.Security.Claims;
using System.Security.Principal;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Security.Claims;
namespace LINGYUN.Abp.Identity.WeChat.Work;
public class AbpWeChatWorkClaimsPrincipalContributor : IAbpClaimsPrincipalContributor, ITransientDependency
{
public async virtual Task ContributeAsync(AbpClaimsPrincipalContributorContext context)
{
var claimsIdentity = context.ClaimsPrincipal.Identities.First();
if (claimsIdentity.HasClaim(x => x.Type == AbpWeChatWorkClaimTypes.UserId))
{
return;
}
var userId = claimsIdentity.FindUserId();
if (userId.HasValue)
{
var userClaimProvider = context.ServiceProvider.GetService<IWeChatWorkUserClaimProvider>();
var weChatWorkUserId = await userClaimProvider?.FindUserIdentifierAsync(userId.Value);
if (!weChatWorkUserId.IsNullOrWhiteSpace())
{
claimsIdentity.AddOrReplace(new Claim(AbpWeChatWorkClaimTypes.UserId, weChatWorkUserId));
context.ClaimsPrincipal.AddIdentityIfNotContains(claimsIdentity);
}
}
}
}

12
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Common/LINGYUN/Abp/WeChat/Common/Messages/AbpWeChatMessageResolveOptions.cs

@ -1,12 +0,0 @@
using System.Collections.Generic;
namespace LINGYUN.Abp.WeChat.Common.Messages;
public class AbpWeChatMessageResolveOptions
{
public List<IMessageResolveContributor> MessageResolvers { get; }
public AbpWeChatMessageResolveOptions()
{
MessageResolvers = new List<IMessageResolveContributor>();
}
}

1
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Common/LINGYUN/Abp/WeChat/Common/Messages/IMessageResolveContributor.cs

@ -1,6 +1,7 @@
using System.Threading.Tasks;
namespace LINGYUN.Abp.WeChat.Common.Messages;
public interface IMessageResolveContributor
{
string Name { get; }

7
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Common/LINGYUN/Abp/WeChat/Common/Messages/IMessageResolver.cs

@ -1,7 +0,0 @@
using System.Threading.Tasks;
namespace LINGYUN.Abp.WeChat.Common.Messages;
public interface IMessageResolver
{
Task<MessageResolveResult> ResolveMessageAsync(MessageResolveData messageData);
}

1
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Common/LINGYUN/Abp/WeChat/Common/Messages/MessageResolveContributorBase.cs

@ -1,6 +1,7 @@
using System.Threading.Tasks;
namespace LINGYUN.Abp.WeChat.Common.Messages;
public abstract class MessageResolveContributorBase : IMessageResolveContributor
{
public abstract string Name { get; }

34
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Common/LINGYUN/Abp/WeChat/Common/Messages/MessageResolver.cs → aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Common/LINGYUN/Abp/WeChat/Common/Messages/MessageResolverBase.cs

@ -1,7 +1,6 @@
using LINGYUN.Abp.WeChat.Common.Crypto;
using LINGYUN.Abp.WeChat.Common.Crypto.Models;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using System;
using System.Linq;
using System.Threading.Tasks;
@ -9,29 +8,25 @@ using System.Xml.Linq;
using Volo.Abp.DependencyInjection;
namespace LINGYUN.Abp.WeChat.Common.Messages;
public class MessageResolver : IMessageResolver, ITransientDependency
public abstract class MessageResolverBase : ITransientDependency
{
private readonly IWeChatCryptoService _cryptoService;
private readonly IServiceProvider _serviceProvider;
private readonly AbpWeChatMessageResolveOptions _options;
public MessageResolver(
IOptions<AbpWeChatMessageResolveOptions> options,
protected MessageResolverBase(
IWeChatCryptoService cryptoService,
IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
_cryptoService = cryptoService;
_options = options.Value;
}
/// <summary>
/// 解析微信服务器推送消息/事件
/// </summary>
/// <param name="messageData"></param>
/// <returns></returns>
public async virtual Task<MessageResolveResult> ResolveMessageAsync(MessageResolveData messageData)
public async virtual Task<MessageResolveResult> ResolveAsync(MessageResolveData messageData)
{
var result = new MessageResolveResult(messageData.Data);
using (var serviceScope = _serviceProvider.CreateScope())
{
/*
@ -65,24 +60,17 @@ public class MessageResolver : IMessageResolver, ITransientDependency
// 经过解密函数得到如上真实数据
var decryptMessage = _cryptoService.Decrypt(cryptoDecryptData);
xmlDocument = XDocument.Parse(decryptMessage);
result.Input = decryptMessage;
}
var context = new MessageResolveContext(result.Input, xmlDocument, serviceScope.ServiceProvider);
var context = new MessageResolveContext(messageData.Data, xmlDocument, serviceScope.ServiceProvider);
foreach (var messageResolver in _options.MessageResolvers)
{
await messageResolver.ResolveAsync(context);
result.AppliedResolvers.Add(messageResolver.Name);
if (context.HasResolvedMessage())
{
result.Message = context.Message;
break;
}
}
return await ResolveMessageAsync(context);
}
return result;
}
/// <summary>
/// 实现具体的解析微信服务器推送消息/事件方法
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
protected abstract Task<MessageResolveResult> ResolveMessageAsync(MessageResolveContext context);
}

7
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Official.Application/LINGYUN/Abp/WeChat/Official/Message/WeChatMessageAppService.cs

@ -1,6 +1,7 @@
using LINGYUN.Abp.WeChat.Common.Crypto;
using LINGYUN.Abp.WeChat.Common.Crypto.Models;
using LINGYUN.Abp.WeChat.Common.Messages;
using LINGYUN.Abp.WeChat.Official.Messages;
using Microsoft.Extensions.Logging;
using System.Threading.Tasks;
using Volo.Abp;
@ -13,9 +14,9 @@ public class WeChatMessageAppService : ApplicationService, IWeChatMessageAppServ
private readonly IWeChatCryptoService _cryptoService;
private readonly AbpWeChatOfficialOptionsFactory _optionsFactory;
private readonly IDistributedEventBus _distributedEventBus;
private readonly IMessageResolver _messageResolver;
private readonly IWeChatOfficialMessageResolver _messageResolver;
public WeChatMessageAppService(
IMessageResolver messageResolver,
IWeChatOfficialMessageResolver messageResolver,
IWeChatCryptoService cryptoService,
IDistributedEventBus distributedEventBus,
AbpWeChatOfficialOptionsFactory optionsFactory)
@ -67,7 +68,7 @@ public class WeChatMessageAppService : ApplicationService, IWeChatMessageAppServ
input.Nonce,
input.Data);
var result = await _messageResolver.ResolveMessageAsync(messageData);
var result = await _messageResolver.ResolveAsync(messageData);
if (result.Message == null)
{
Logger.LogWarning(input.Data);

3
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Official/LINGYUN/Abp/WeChat/Official/AbpWeChatOfficialModule.cs

@ -40,10 +40,7 @@ public class AbpWeChatOfficialModule : AbpModule
options.MapMessage("shortvideo", context => context.GetWeChatMessage<VideoMessage>());
options.MapMessage("location", context => context.GetWeChatMessage<GeoLocationMessage>());
options.MapMessage("link", context => context.GetWeChatMessage<LinkMessage>());
});
Configure<AbpWeChatMessageResolveOptions>(options =>
{
// 事件处理器
options.MessageResolvers.AddIfNotContains(new WeChatOfficialEventResolveContributor());
// 消息处理器

2
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Official/LINGYUN/Abp/WeChat/Official/Messages/AbpWeChatOfficialMessageResolveOptions.cs

@ -5,10 +5,12 @@ using System.Collections.Generic;
namespace LINGYUN.Abp.WeChat.Official.Messages;
public class AbpWeChatOfficialMessageResolveOptions
{
public List<IMessageResolveContributor> MessageResolvers { get; }
public IDictionary<string, Func<IMessageResolveContext, WeChatEventMessage>> EventMaps { get; }
public IDictionary<string, Func<IMessageResolveContext, WeChatGeneralMessage>> MessageMaps { get; }
public AbpWeChatOfficialMessageResolveOptions()
{
MessageResolvers = new List<IMessageResolveContributor>();
EventMaps = new Dictionary<string, Func<IMessageResolveContext, WeChatEventMessage>>();
MessageMaps = new Dictionary<string, Func<IMessageResolveContext, WeChatGeneralMessage>>();
}

16
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Official/LINGYUN/Abp/WeChat/Official/Messages/IWeChatOfficialMessageResolver.cs

@ -0,0 +1,16 @@
using LINGYUN.Abp.WeChat.Common.Messages;
using System.Threading.Tasks;
namespace LINGYUN.Abp.WeChat.Official.Messages;
/// <summary>
/// 微信公众号消息解析器
/// </summary>
public interface IWeChatOfficialMessageResolver
{
/// <summary>
/// 解析微信公众号消息
/// </summary>
/// <param name="messageData">公众号消息</param>
/// <returns></returns>
Task<MessageResolveResult> ResolveAsync(MessageResolveData messageData);
}

5
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Official/LINGYUN/Abp/WeChat/Official/Messages/WeChatOfficialEventResolveContributor.cs

@ -1,6 +1,4 @@
using LINGYUN.Abp.WeChat.Common.Messages;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using System;
using System.Threading.Tasks;
@ -12,9 +10,8 @@ public class WeChatOfficialEventResolveContributor : WeChatOfficialMessageResolv
{
public override string Name => "WeChat.Official.Event";
protected override Task ResolveWeChatMessageAsync(IMessageResolveContext context)
protected override Task ResolveMessageAsync(IMessageResolveContext context, AbpWeChatOfficialMessageResolveOptions options)
{
var options = context.ServiceProvider.GetRequiredService<IOptions<AbpWeChatOfficialMessageResolveOptions>>().Value;
var messageType = context.GetMessageData("MsgType");
var eventName = context.GetMessageData("Event");
if ("event".Equals(messageType, StringComparison.InvariantCultureIgnoreCase) &&

5
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Official/LINGYUN/Abp/WeChat/Official/Messages/WeChatOfficialMessageResolveContributor.cs

@ -1,6 +1,4 @@
using LINGYUN.Abp.WeChat.Common.Messages;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using System.Threading.Tasks;
namespace LINGYUN.Abp.WeChat.Official.Messages;
@ -11,9 +9,8 @@ public class WeChatOfficialMessageResolveContributor : WeChatOfficialMessageReso
{
public override string Name => "WeChat.Official.Message";
protected override Task ResolveWeChatMessageAsync(IMessageResolveContext context)
protected override Task ResolveMessageAsync(IMessageResolveContext context, AbpWeChatOfficialMessageResolveOptions options)
{
var options = context.ServiceProvider.GetRequiredService<IOptions<AbpWeChatOfficialMessageResolveOptions>>().Value;
var messageType = context.GetMessageData("MsgType");
if (options.MessageMaps.TryGetValue(messageType, out var messageFactory))
{

11
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Official/LINGYUN/Abp/WeChat/Official/Messages/WeChatOfficialMessageResolveContributorBase.cs

@ -1,4 +1,6 @@
using LINGYUN.Abp.WeChat.Common.Messages;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using System.Threading.Tasks;
namespace LINGYUN.Abp.WeChat.Official.Messages;
@ -6,13 +8,10 @@ public abstract class WeChatOfficialMessageResolveContributorBase : MessageResol
{
public override Task ResolveAsync(IMessageResolveContext context)
{
if (!context.HasMessageKey("AgentID"))
{
return ResolveWeChatMessageAsync(context);
}
var options = context.ServiceProvider.GetRequiredService<IOptions<AbpWeChatOfficialMessageResolveOptions>>().Value;
return Task.CompletedTask;
return ResolveMessageAsync(context, options);
}
protected abstract Task ResolveWeChatMessageAsync(IMessageResolveContext context);
protected abstract Task ResolveMessageAsync(IMessageResolveContext context, AbpWeChatOfficialMessageResolveOptions options);
}

39
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Official/LINGYUN/Abp/WeChat/Official/Messages/WeChatOfficialMessageResolver.cs

@ -0,0 +1,39 @@
using LINGYUN.Abp.WeChat.Common.Crypto;
using LINGYUN.Abp.WeChat.Common.Messages;
using Microsoft.Extensions.Options;
using System;
using System.Threading.Tasks;
namespace LINGYUN.Abp.WeChat.Official.Messages;
public class WeChatOfficialMessageResolver : MessageResolverBase, IWeChatOfficialMessageResolver
{
private readonly AbpWeChatOfficialMessageResolveOptions _options;
public WeChatOfficialMessageResolver(
IWeChatCryptoService cryptoService,
IServiceProvider serviceProvider,
IOptions<AbpWeChatOfficialMessageResolveOptions> options)
: base(cryptoService, serviceProvider)
{
_options = options.Value;
}
protected async override Task<MessageResolveResult> ResolveMessageAsync(MessageResolveContext context)
{
var result = new MessageResolveResult(context.Origin);
foreach (var messageResolver in _options.MessageResolvers)
{
await messageResolver.ResolveAsync(context);
result.AppliedResolvers.Add(messageResolver.Name);
if (context.HasResolvedMessage())
{
result.Message = context.Message;
break;
}
}
return result;
}
}

7
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.Application/LINGYUN/Abp/WeChat/Work/Message/WeChatWorkMessageAppService.cs

@ -1,6 +1,7 @@
using LINGYUN.Abp.WeChat.Common.Crypto;
using LINGYUN.Abp.WeChat.Common.Crypto.Models;
using LINGYUN.Abp.WeChat.Common.Messages;
using LINGYUN.Abp.WeChat.Work.Common.Messages;
using LINGYUN.Abp.WeChat.Work.Settings;
using Microsoft.Extensions.Logging;
using System.Linq;
@ -14,9 +15,9 @@ public class WeChatWorkMessageAppService : ApplicationService, IWeChatWorkMessag
{
private readonly IWeChatCryptoService _cryptoService;
private readonly IDistributedEventBus _distributedEventBus;
private readonly IMessageResolver _messageResolver;
private readonly IWeChatWorkMessageResolver _messageResolver;
public WeChatWorkMessageAppService(
IMessageResolver messageResolver,
IWeChatWorkMessageResolver messageResolver,
IWeChatCryptoService cryptoService,
IDistributedEventBus distributedEventBus)
{
@ -82,7 +83,7 @@ public class WeChatWorkMessageAppService : ApplicationService, IWeChatWorkMessag
input.Nonce,
input.Data);
var result = await _messageResolver.ResolveMessageAsync(messageData);
var result = await _messageResolver.ResolveAsync(messageData);
if (result.Message == null)
{
Logger.LogWarning(input.Data);

1
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.Common/LINGYUN.Abp.WeChat.Work.Common.csproj

@ -10,6 +10,7 @@
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
<GenerateDocumentationFile>True</GenerateDocumentationFile>
<RootNamespace />
</PropertyGroup>

5
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.Common/LINGYUN/Abp/WeChat/Work/Common/AbpWeChatWorkCommonModule.cs

@ -57,6 +57,8 @@ public class AbpWeChatWorkCommonModule : AbpModule
_ => throw new AbpWeChatException($"Contact change event {changeType} is not mounted!"),
};
});
options.MapEvent("book_meeting_room", context => context.GetWeChatMessage<BookMeetingRoomEvent>());
options.MapEvent("cancel_meeting_room", context => context.GetWeChatMessage<CancelMeetingRoomEvent>());
options.MapMessage("text", context => context.GetWeChatMessage<TextMessage>());
options.MapMessage("image", context => context.GetWeChatMessage<PictureMessage>());
@ -65,10 +67,7 @@ public class AbpWeChatWorkCommonModule : AbpModule
options.MapMessage("shortvideo", context => context.GetWeChatMessage<VideoMessage>());
options.MapMessage("location", context => context.GetWeChatMessage<GeoLocationMessage>());
options.MapMessage("link", context => context.GetWeChatMessage<LinkMessage>());
});
Configure<AbpWeChatMessageResolveOptions>(options =>
{
// 事件处理器
options.MessageResolvers.AddIfNotContains(new WeChatWorkEventResolveContributor());
// 消息处理器

2
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.Common/LINGYUN/Abp/WeChat/Work/Common/Messages/AbpWeChatWorkMessageResolveOptions.cs

@ -5,10 +5,12 @@ using System.Collections.Generic;
namespace LINGYUN.Abp.WeChat.Work.Common.Messages;
public class AbpWeChatWorkMessageResolveOptions
{
public List<IMessageResolveContributor> MessageResolvers { get; }
public IDictionary<string, Func<IMessageResolveContext, WeChatWorkEventMessage>> EventMaps { get; }
public IDictionary<string, Func<IMessageResolveContext, WeChatWorkGeneralMessage>> MessageMaps { get; }
public AbpWeChatWorkMessageResolveOptions()
{
MessageResolvers = new List<IMessageResolveContributor>();
EventMaps = new Dictionary<string, Func<IMessageResolveContext, WeChatWorkEventMessage>>();
MessageMaps = new Dictionary<string, Func<IMessageResolveContext, WeChatWorkGeneralMessage>>();
}

16
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.Common/LINGYUN/Abp/WeChat/Work/Common/Messages/IWeChatWorkMessageResolver.cs

@ -0,0 +1,16 @@
using LINGYUN.Abp.WeChat.Common.Messages;
using System.Threading.Tasks;
namespace LINGYUN.Abp.WeChat.Work.Common.Messages;
/// <summary>
/// 企业微信消息解析器
/// </summary>
public interface IWeChatWorkMessageResolver
{
/// <summary>
/// 解析企业微信消息
/// </summary>
/// <param name="messageData">企业微信消息</param>
/// <returns></returns>
Task<MessageResolveResult> ResolveAsync(MessageResolveData messageData);
}

30
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.Common/LINGYUN/Abp/WeChat/Work/Common/Messages/Models/BookMeetingRoomEvent.cs

@ -0,0 +1,30 @@
using LINGYUN.Abp.WeChat.Common.Messages;
using System.Xml.Serialization;
using Volo.Abp.EventBus;
namespace LINGYUN.Abp.WeChat.Work.Common.Messages.Models;
/// <summary>
/// 会议室预定事件
/// </summary>
/// <remarks>
/// 当用户在企业微信预定会议室时,会触发该事件回调给会议室系统应用。
/// </remarks>
[EventName("book_meeting_room")]
public class BookMeetingRoomEvent : WeChatWorkEventMessage
{
/// <summary>
/// 会议室id
/// </summary>
[XmlElement("MeetingRoomId")]
public int MeetingRoomId { get; set; }
/// <summary>
/// 预定id,可根据该ID查询具体的会议预定情况
/// </summary>
[XmlElement("BookingId")]
public string BookingId { get; set; }
public override WeChatMessageEto ToEto()
{
return new WeChatWorkEventMessageEto<BookMeetingRoomEvent>(this);
}
}

30
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.Common/LINGYUN/Abp/WeChat/Work/Common/Messages/Models/CancelMeetingRoomEvent.cs

@ -0,0 +1,30 @@
using LINGYUN.Abp.WeChat.Common.Messages;
using System.Xml.Serialization;
using Volo.Abp.EventBus;
namespace LINGYUN.Abp.WeChat.Work.Common.Messages.Models;
/// <summary>
/// 会议室取消事件
/// </summary>
/// <remarks>
/// 当用户在企业微信取消预定会议室时,会触发该事件回调给会议室系统应用;如果该会议室由自建应用预定,除了会议室系统应用外,也会回调给对应的自建应用。
/// </remarks>
[EventName("cancel_meeting_room")]
public class CancelMeetingRoomEvent : WeChatWorkEventMessage
{
/// <summary>
/// 会议室id
/// </summary>
[XmlElement("MeetingRoomId")]
public int MeetingRoomId { get; set; }
/// <summary>
/// 预定id,可根据该ID查询具体的会议预定情况
/// </summary>
[XmlElement("BookingId")]
public string BookingId { get; set; }
public override WeChatMessageEto ToEto()
{
return new WeChatWorkEventMessageEto<CancelMeetingRoomEvent>(this);
}
}

5
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.Common/LINGYUN/Abp/WeChat/Work/Common/Messages/WeChatWorkEventResolveContributor.cs

@ -1,6 +1,4 @@
using LINGYUN.Abp.WeChat.Common.Messages;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using System;
using System.Threading.Tasks;
@ -12,9 +10,8 @@ public class WeChatWorkEventResolveContributor : WeChatWorkMessageResolveContrib
{
public override string Name => "WeChat.Work.Event";
protected override Task ResolveWeComMessageAsync(IMessageResolveContext context)
protected override Task ResolveMessageAsync(IMessageResolveContext context, AbpWeChatWorkMessageResolveOptions options)
{
var options = context.ServiceProvider.GetRequiredService<IOptions<AbpWeChatWorkMessageResolveOptions>>().Value;
var messageType = context.GetMessageData("MsgType");
var eventName = context.GetMessageData("Event");
if ("event".Equals(messageType, StringComparison.InvariantCultureIgnoreCase) &&

5
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.Common/LINGYUN/Abp/WeChat/Work/Common/Messages/WeChatWorkMessageResolveContributor.cs

@ -1,6 +1,4 @@
using LINGYUN.Abp.WeChat.Common.Messages;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using System.Threading.Tasks;
namespace LINGYUN.Abp.WeChat.Work.Common.Messages;
@ -11,9 +9,8 @@ public class WeChatWorkMessageResolveContributor : WeChatWorkMessageResolveContr
{
public override string Name => "WeChat.Work.Message";
protected override Task ResolveWeComMessageAsync(IMessageResolveContext context)
protected override Task ResolveMessageAsync(IMessageResolveContext context, AbpWeChatWorkMessageResolveOptions options)
{
var options = context.ServiceProvider.GetRequiredService<IOptions<AbpWeChatWorkMessageResolveOptions>>().Value;
var messageType = context.GetMessageData("MsgType");
if (options.MessageMaps.TryGetValue(messageType, out var messageFactory))
{

12
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.Common/LINGYUN/Abp/WeChat/Work/Common/Messages/WeChatWorkMessageResolveContributorBase.cs

@ -1,4 +1,6 @@
using LINGYUN.Abp.WeChat.Common.Messages;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using System.Threading.Tasks;
namespace LINGYUN.Abp.WeChat.Work.Common.Messages;
@ -6,14 +8,10 @@ public abstract class WeChatWorkMessageResolveContributorBase : MessageResolveCo
{
public override Task ResolveAsync(IMessageResolveContext context)
{
// 企业微信消息需要企业标识字段
if (context.HasMessageKey("AgentID"))
{
return ResolveWeComMessageAsync(context);
}
var options = context.ServiceProvider.GetRequiredService<IOptions<AbpWeChatWorkMessageResolveOptions>>().Value;
return Task.CompletedTask;
return ResolveMessageAsync(context, options);
}
protected abstract Task ResolveWeComMessageAsync(IMessageResolveContext context);
protected abstract Task ResolveMessageAsync(IMessageResolveContext context, AbpWeChatWorkMessageResolveOptions options);
}

39
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.Common/LINGYUN/Abp/WeChat/Work/Common/Messages/WeChatWorkMessageResolver.cs

@ -0,0 +1,39 @@
using LINGYUN.Abp.WeChat.Common.Crypto;
using LINGYUN.Abp.WeChat.Common.Messages;
using Microsoft.Extensions.Options;
using System;
using System.Threading.Tasks;
namespace LINGYUN.Abp.WeChat.Work.Common.Messages;
public class WeChatWorkMessageResolver : MessageResolverBase, IWeChatWorkMessageResolver
{
private readonly AbpWeChatWorkMessageResolveOptions _options;
public WeChatWorkMessageResolver(
IWeChatCryptoService cryptoService,
IServiceProvider serviceProvider,
IOptions<AbpWeChatWorkMessageResolveOptions> options)
: base(cryptoService, serviceProvider)
{
_options = options.Value;
}
protected async override Task<MessageResolveResult> ResolveMessageAsync(MessageResolveContext context)
{
var result = new MessageResolveResult(context.Origin);
foreach (var messageResolver in _options.MessageResolvers)
{
await messageResolver.ResolveAsync(context);
result.AppliedResolvers.Add(messageResolver.Name);
if (context.HasResolvedMessage())
{
result.Message = context.Message;
break;
}
}
return result;
}
}

1
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work/LINGYUN.Abp.WeChat.Work.csproj

@ -10,6 +10,7 @@
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
<GenerateDocumentationFile>True</GenerateDocumentationFile>
<RootNamespace />
</PropertyGroup>

18
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work/LINGYUN/Abp/WeChat/Work/AbpWeChatWorkModule.cs

@ -42,20 +42,8 @@ public class AbpWeChatWorkModule : AbpModule
options.MapCodeNamespace(WeChatWorkErrorCodes.Namespace, typeof(WeChatWorkResource));
});
context.Services.AddHttpClient(AbpWeChatWorkGlobalConsts.ApiClient,
options =>
{
options.BaseAddress = new Uri("https://qyapi.weixin.qq.com");
});
context.Services.AddHttpClient(AbpWeChatWorkGlobalConsts.OAuthClient,
options =>
{
options.BaseAddress = new Uri("https://open.weixin.qq.com");
});
context.Services.AddHttpClient(AbpWeChatWorkGlobalConsts.LoginClient,
options =>
{
options.BaseAddress = new Uri("https://login.work.weixin.qq.com");
});
context.Services.AddApiClient();
context.Services.AddOAuthClient();
context.Services.AddLoginClient();
}
}

7
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work/LINGYUN/Abp/WeChat/Work/WeChatWorkRequest.cs

@ -7,6 +7,13 @@ public abstract class WeChatWorkRequest
{
public virtual string SerializeToJson()
{
Validate();
return WeChatObjectSerializeExtensions.SerializeToJson(this);
}
protected virtual void Validate()
{
}
}

61
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work/Microsoft/Extensions/DependencyInjection/IHttpClientFactoryWeChatWorkExtensions.cs

@ -0,0 +1,61 @@
using LINGYUN.Abp.WeChat.Work;
using System;
using System.Net.Http;
namespace Microsoft.Extensions.DependencyInjection;
public static class IHttpClientFactoryWeChatWorkExtensions
{
internal static IServiceCollection AddApiClient(this IServiceCollection services, Action<HttpClient> configureClient = null)
{
services.AddHttpClient(AbpWeChatWorkGlobalConsts.ApiClient,
options =>
{
options.BaseAddress = new Uri("https://qyapi.weixin.qq.com");
configureClient?.Invoke(options);
});
return services;
}
public static HttpClient CreateWeChatWorkApiClient(this IHttpClientFactory httpClientFactory)
{
return httpClientFactory.CreateClient(AbpWeChatWorkGlobalConsts.ApiClient);
}
internal static IServiceCollection AddOAuthClient(this IServiceCollection services, Action<HttpClient> configureClient = null)
{
services.AddHttpClient(AbpWeChatWorkGlobalConsts.OAuthClient,
options =>
{
options.BaseAddress = new Uri("https://open.weixin.qq.com");
configureClient?.Invoke(options);
});
return services;
}
public static HttpClient CreateWeChatWorkOAuthClient(this IHttpClientFactory httpClientFactory)
{
return httpClientFactory.CreateClient(AbpWeChatWorkGlobalConsts.OAuthClient);
}
internal static IServiceCollection AddLoginClient(this IServiceCollection services, Action<HttpClient> configureClient = null)
{
services.AddHttpClient(AbpWeChatWorkGlobalConsts.LoginClient,
options =>
{
options.BaseAddress = new Uri("https://login.work.weixin.qq.com");
configureClient?.Invoke(options);
});
return services;
}
public static HttpClient CreateWeChatWorkLoginClient(this IHttpClientFactory httpClientFactory)
{
return httpClientFactory.CreateClient(AbpWeChatWorkGlobalConsts.LoginClient);
}
}
Loading…
Cancel
Save