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; using YD_Event.Core.Infrastructure.WeChat.Dto; namespace YD_Event.Core.Infrastructure.WeChat; public class WeChatService : ITransient { private readonly IHttpClientFactory _httpClientFactory; private readonly ILogger _logger; private readonly WeChatOptions _options; public WeChatService(IHttpClientFactory httpClientFactory, ILogger logger, IOptions options) { _httpClientFactory = httpClientFactory; _logger = logger; _options = options.Value; } /// /// code换取session_key /// /// /// public async Task 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() .Or() .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(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("微信服务暂不可用,请稍后重试"); } } }