| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208 |
- // Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
- //
- // 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
- //
- // 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
- using Newtonsoft.Json;
- namespace Admin.NET.Core.Service;
- /// <summary>
- /// 微信API客户端
- /// </summary>
- public partial class WechatApiClientFactory : ISingleton
- {
- private readonly IHttpClientFactory _httpClientFactory;
- public readonly WechatOptions _wechatOptions;
- private readonly SysCacheService _sysCacheService;
- public WechatApiClientFactory(IHttpClientFactory httpClientFactory, IOptions<WechatOptions> wechatOptions, SysCacheService sysCacheService)
- {
- _httpClientFactory = httpClientFactory ?? throw new ArgumentNullException(nameof(httpClientFactory));
- _wechatOptions = wechatOptions.Value ?? throw new ArgumentNullException(nameof(wechatOptions));
- _sysCacheService = sysCacheService;
- }
- /// <summary>
- /// 微信公众号
- /// </summary>
- /// <returns></returns>
- public WechatApiClient CreateWechatClient()
- {
- if (string.IsNullOrEmpty(_wechatOptions.WechatAppId) || string.IsNullOrEmpty(_wechatOptions.WechatAppSecret))
- throw Oops.Oh("微信公众号配置错误");
- var client = WechatApiClientBuilder.Create(new WechatApiClientOptions()
- {
- AppId = _wechatOptions.WechatAppId,
- AppSecret = _wechatOptions.WechatAppSecret,
- PushToken = _wechatOptions.WechatToken,
- PushEncodingAESKey = _wechatOptions.WechatEncodingAESKey,
- })
- .UseHttpClient(_httpClientFactory.CreateClient(), disposeClient: false) // 设置 HttpClient 不随客户端一同销毁
- .Build();
- client.Configure(config =>
- {
- JsonSerializerSettings jsonSerializerSettings = NewtonsoftJsonSerializer.GetDefaultSerializerSettings();
- jsonSerializerSettings.Formatting = Formatting.Indented;
- config.JsonSerializer = new NewtonsoftJsonSerializer(jsonSerializerSettings); // 指定 System.Text.Json JSON序列化
- // config.JsonSerializer = new SystemTextJsonSerializer(jsonSerializerOptions); // 指定 Newtonsoft.Json JSON序列化
- });
- return client;
- }
- /// <summary>
- /// 微信小程序
- /// </summary>
- /// <returns></returns>
- public WechatApiClient CreateWxOpenClient()
- {
- if (string.IsNullOrEmpty(_wechatOptions.WxOpenAppId) || string.IsNullOrEmpty(_wechatOptions.WxOpenAppSecret))
- throw Oops.Oh("微信小程序配置错误");
- var client = WechatApiClientBuilder.Create(new WechatApiClientOptions()
- {
- AppId = _wechatOptions.WxOpenAppId,
- AppSecret = _wechatOptions.WxOpenAppSecret,
- PushToken = _wechatOptions.WxToken,
- PushEncodingAESKey = _wechatOptions.WxEncodingAESKey,
- })
- .UseHttpClient(_httpClientFactory.CreateClient(), disposeClient: false) // 设置 HttpClient 不随客户端一同销毁
- .Build();
- client.Configure(config =>
- {
- JsonSerializerSettings jsonSerializerSettings = NewtonsoftJsonSerializer.GetDefaultSerializerSettings();
- jsonSerializerSettings.Formatting = Formatting.Indented;
- config.JsonSerializer = new NewtonsoftJsonSerializer(jsonSerializerSettings); // 指定 System.Text.Json JSON序列化
- // config.JsonSerializer = new SystemTextJsonSerializer(jsonSerializerOptions); // 指定 Newtonsoft.Json JSON序列化
- });
- return client;
- }
- /// <summary>
- /// 获取微信公众号AccessToken
- /// </summary>
- /// <returns></returns>
- public async Task<string> TryGetWechatAccessTokenAsync()
- {
- if (!_sysCacheService.ExistKey($"WxAccessToken_{_wechatOptions.WechatAppId}") || string.IsNullOrEmpty(_sysCacheService.Get<string>($"WxAccessToken_{_wechatOptions.WechatAppId}")))
- {
- var client = CreateWechatClient();
- var reqCgibinToken = new CgibinTokenRequest();
- var resCgibinToken = await client.ExecuteCgibinTokenAsync(reqCgibinToken);
- if (resCgibinToken.ErrorCode != (int)WechatReturnCodeEnum.请求成功)
- throw Oops.Oh(resCgibinToken.ErrorMessage + " " + resCgibinToken.ErrorCode);
- _sysCacheService.Set($"WxAccessToken_{_wechatOptions.WechatAppId}", resCgibinToken.AccessToken, TimeSpan.FromSeconds(resCgibinToken.ExpiresIn - 60));
- }
- return _sysCacheService.Get<string>($"WxAccessToken_{_wechatOptions.WechatAppId}");
- }
- /// <summary>
- /// 获取微信小程序AccessToken
- /// </summary>
- /// <returns></returns>
- public async Task<string> TryGetWxOpenAccessTokenAsync()
- {
- if (!_sysCacheService.ExistKey($"WxAccessToken_{_wechatOptions.WxOpenAppId}") || string.IsNullOrEmpty(_sysCacheService.Get<string>($"WxAccessToken_{_wechatOptions.WxOpenAppId}")))
- {
- var client = CreateWxOpenClient();
- var reqCgibinToken = new CgibinTokenRequest();
- var resCgibinToken = await client.ExecuteCgibinTokenAsync(reqCgibinToken);
- if (resCgibinToken.ErrorCode != (int)WechatReturnCodeEnum.请求成功)
- throw Oops.Oh(resCgibinToken.ErrorMessage + " " + resCgibinToken.ErrorCode);
- _sysCacheService.Set($"WxAccessToken_{_wechatOptions.WxOpenAppId}", resCgibinToken.AccessToken, TimeSpan.FromSeconds(resCgibinToken.ExpiresIn - 60));
- }
- return _sysCacheService.Get<string>($"WxAccessToken_{_wechatOptions.WxOpenAppId}");
- }
- /// <summary>
- /// 检查微信公众号AccessToken
- /// </summary>
- /// <returns></returns>
- public async Task CheckWechatAccessTokenAsync()
- {
- if (string.IsNullOrEmpty(_wechatOptions.WechatAppId) || string.IsNullOrEmpty(_wechatOptions.WechatAppSecret)) return;
- var req = new CgibinOpenApiQuotaGetRequest
- {
- AccessToken = await TryGetWechatAccessTokenAsync(),
- CgiPath = "/cgi-bin/token"
- };
- var client = CreateWechatClient();
- var res = await client.ExecuteCgibinOpenApiQuotaGetAsync(req);
- var originColor = Console.ForegroundColor;
- if (res.ErrorCode != (int)WechatReturnCodeEnum.请求成功)
- {
- _sysCacheService.Remove($"WxAccessToken_{_wechatOptions.WechatAppId}");
- Console.ForegroundColor = ConsoleColor.Red;
- Console.WriteLine("【" + DateTime.Now + "】" + _wechatOptions.WxOpenAppId + " 微信公众号令牌 无效");
- }
- else
- {
- Console.ForegroundColor = ConsoleColor.Magenta;
- Console.WriteLine("【" + DateTime.Now + "】" + _wechatOptions.WxOpenAppId + " 微信公众号令牌 有效");
- }
- Console.ForegroundColor = originColor;
- }
- /// <summary>
- /// 检查微信小程序AccessToken
- /// </summary>
- /// <returns></returns>
- public async Task CheckWxOpenAccessTokenAsync()
- {
- if (string.IsNullOrEmpty(_wechatOptions.WxOpenAppId) || string.IsNullOrEmpty(_wechatOptions.WxOpenAppSecret)) return;
- var req = new CgibinOpenApiQuotaGetRequest
- {
- AccessToken = await TryGetWxOpenAccessTokenAsync(),
- CgiPath = "/cgi-bin/token"
- };
- var client = CreateWxOpenClient();
- var res = await client.ExecuteCgibinOpenApiQuotaGetAsync(req);
- var originColor = Console.ForegroundColor;
- if (res.ErrorCode != (int)WechatReturnCodeEnum.请求成功)
- {
- _sysCacheService.Remove($"WxAccessToken_{_wechatOptions.WxOpenAppId}");
- Console.ForegroundColor = ConsoleColor.Red;
- Console.WriteLine("【" + DateTime.Now + "】" + _wechatOptions.WxOpenAppId + " 微信小程序令牌 无效");
- }
- else
- {
- Console.ForegroundColor = ConsoleColor.Magenta;
- Console.WriteLine("【" + DateTime.Now + "】" + _wechatOptions.WxOpenAppId + " 微信小程序令牌 有效");
- }
- Console.ForegroundColor = originColor;
- }
- /// <summary>
- /// 获取微信JS接口临时票据jsapi_ticket
- /// </summary>
- /// <returns></returns>
- public async Task<string> TryGetWechatJsApiTicketAsync()
- {
- if (!_sysCacheService.ExistKey($"WxJsApiTicket_{_wechatOptions.WechatAppId}") || string.IsNullOrEmpty(_sysCacheService.Get<string>($"WxJsApiTicket_{_wechatOptions.WechatAppId}")))
- {
- var accessToken = await TryGetWechatAccessTokenAsync();
- var client = CreateWechatClient();
- var request = new CgibinTicketGetTicketRequest()
- {
- AccessToken = accessToken
- };
- var response = await client.ExecuteCgibinTicketGetTicketAsync(request);
- if (!response.IsSuccessful())
- throw Oops.Oh(response.ErrorMessage + " " + response.ErrorCode);
- _sysCacheService.Set($"WxJsApiTicket_{_wechatOptions.WechatAppId}", response.Ticket, TimeSpan.FromSeconds(response.ExpiresIn - 60));
- }
- return _sysCacheService.Get<string>($"WxJsApiTicket_{_wechatOptions.WechatAppId}");
- }
- }
|