94 lines
3.1 KiB
C#
94 lines
3.1 KiB
C#
using System.Net.Http.Json;
|
||
using Microsoft.Extensions.Logging;
|
||
using Microsoft.Extensions.Options;
|
||
using Newtonsoft.Json;
|
||
using Polly;
|
||
using Polly.Retry;
|
||
using YD_Event.Core.Options;
|
||
using Furion.DependencyInjection;
|
||
using System.Net.Http;
|
||
using System.Threading.Tasks;
|
||
using Furion.FriendlyException;
|
||
|
||
namespace YD_Event.Core.Infrastructure.WeChat;
|
||
|
||
public class WeChatService : ITransient
|
||
{
|
||
private readonly IHttpClientFactory _httpClientFactory;
|
||
private readonly ILogger<WeChatService> _logger;
|
||
private readonly WeChatOptions _options;
|
||
|
||
public WeChatService(IHttpClientFactory httpClientFactory, ILogger<WeChatService> logger, IOptions<WeChatOptions> options)
|
||
{
|
||
_httpClientFactory = httpClientFactory;
|
||
_logger = logger;
|
||
_options = options.Value;
|
||
}
|
||
|
||
/// <summary>
|
||
/// code换取session_key
|
||
/// </summary>
|
||
/// <param name="code"></param>
|
||
/// <returns></returns>
|
||
public async Task<WeChatCode2SessionResponse> Code2Session(string code)
|
||
{
|
||
var url = $"https://api.weixin.qq.com/sns/jscode2session?appid={_options.AppId}&secret={_options.Secret}&js_code={code}&grant_type=authorization_code";
|
||
|
||
// 定义重试策略:3秒超时,重试2次
|
||
var retryPolicy = Policy
|
||
.Handle<HttpRequestException>()
|
||
.Or<TaskCanceledException>()
|
||
.WaitAndRetryAsync(2, retryAttempt => TimeSpan.FromSeconds(1), (exception, timeSpan, retryCount, context) =>
|
||
{
|
||
_logger.LogWarning($"WeChat API Request Failed. Retry {retryCount}. Error: {exception.Message}");
|
||
});
|
||
|
||
var timeoutPolicy = Policy.TimeoutAsync(3); // 3秒超时
|
||
|
||
var policyWrap = Policy.WrapAsync(retryPolicy, timeoutPolicy);
|
||
|
||
try
|
||
{
|
||
return await policyWrap.ExecuteAsync(async () =>
|
||
{
|
||
var client = _httpClientFactory.CreateClient();
|
||
var response = await client.GetAsync(url);
|
||
response.EnsureSuccessStatusCode();
|
||
var content = await response.Content.ReadAsStringAsync();
|
||
var result = JsonConvert.DeserializeObject<WeChatCode2SessionResponse>(content);
|
||
|
||
if (result == null || result.ErrCode != 0)
|
||
{
|
||
_logger.LogError($"WeChat Code2Session Error: {content}");
|
||
throw Oops.Bah($"微信接口调用失败: {result?.ErrMsg ?? "未知错误"}");
|
||
}
|
||
|
||
return result;
|
||
});
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
_logger.LogError(ex, "WeChat Code2Session Exception");
|
||
throw Oops.Bah("微信服务暂不可用,请稍后重试");
|
||
}
|
||
}
|
||
}
|
||
|
||
public class WeChatCode2SessionResponse
|
||
{
|
||
[JsonProperty("openid")]
|
||
public string OpenId { get; set; }
|
||
|
||
[JsonProperty("session_key")]
|
||
public string SessionKey { get; set; }
|
||
|
||
[JsonProperty("unionid")]
|
||
public string UnionId { get; set; }
|
||
|
||
[JsonProperty("errcode")]
|
||
public int ErrCode { get; set; }
|
||
|
||
[JsonProperty("errmsg")]
|
||
public string ErrMsg { get; set; }
|
||
}
|