From 5c45bc53e2c18e45130c21048df4af4896455c6d Mon Sep 17 00:00:00 2001 From: sunpengfei <i@angelzzz.com> Date: 星期五, 12 九月 2025 15:58:48 +0800 Subject: [PATCH] feat:开发 --- FlexJobApi.Core/Utils/WxmpUtils/WxmpUtils.cs | 87 +++++++++++++++++++++++++++++++++++++++++-- 1 files changed, 83 insertions(+), 4 deletions(-) diff --git a/FlexJobApi.Core/Utils/WxmpUtils/WxmpUtils.cs b/FlexJobApi.Core/Utils/WxmpUtils/WxmpUtils.cs index 0a200da..3f89a7a 100644 --- a/FlexJobApi.Core/Utils/WxmpUtils/WxmpUtils.cs +++ b/FlexJobApi.Core/Utils/WxmpUtils/WxmpUtils.cs @@ -1,10 +1,19 @@ -锘縰sing Furion.FriendlyException; +锘縰sing Aliyun.OSS; +using Azure.Core; +using FlexJobApi.Core.Utils.WxmpUtils; +using Furion.FriendlyException; using Furion.HttpRemote; +using Mapster; +using Microsoft.Extensions.Caching.Distributed; using Microsoft.Extensions.Options; +using Newtonsoft.Json; using System; using System.Collections.Generic; +using System.IO; using System.Linq; +using System.Net.Http.Json; using System.Text; +using System.Text.Json.Nodes; using System.Threading; using System.Threading.Tasks; @@ -17,23 +26,26 @@ { private readonly IOptions<WxmpOptions> options; private readonly IHttpRemoteService httpRemoteService; + private readonly IDistributedCache distributedCache; public WxmpUtils( IOptions<WxmpOptions> options, - IHttpRemoteService httpRemoteService) + IHttpRemoteService httpRemoteService, + IDistributedCache distributedCache) { this.options = options; this.httpRemoteService = httpRemoteService; + this.distributedCache = distributedCache; } - public async Task<WxmpSnsJscode2sessionCallback> SnsJscode2sessionAsync(EnumUserType userType, string code, CancellationToken cancellationToken = default) + public async Task<WxmpSnsJscode2sessionResponse> SnsJscode2sessionAsync(EnumUserType userType, string code, CancellationToken cancellationToken = default) { var option = options.Value.Items.FirstOrDefault(it => it.Code == userType.ToString()); if (option == null || option.AppId.IsNull() || option.AppSecret.IsNull()) throw Oops.Oh(EnumErrorCodeType.s400, "鐧诲綍澶辫触锛岀己澶遍厤缃細WxmpOptions"); if (code.IsNull()) throw Oops.Oh(EnumErrorCodeType.s400, "璇峰~鍐橶xmpCode"); - var callback = await httpRemoteService.GetAsAsync<WxmpSnsJscode2sessionCallback>("https://api.weixin.qq.com/sns/jscode2session", + var callback = await httpRemoteService.GetAsAsync<WxmpSnsJscode2sessionResponse>("https://api.weixin.qq.com/sns/jscode2session", builder => builder.WithQueryParameters(new Dictionary<string, string> { { "appid", option.AppId }, @@ -45,5 +57,72 @@ throw Oops.Oh(EnumErrorCodeType.s510, $"鐧诲綍澶辫触锛歿callback.errmsg}锛岃鑱旂郴绠$悊鍛�"); return callback; } + + /// <summary> + /// 鑾峰彇灏忕▼搴忔帴鍙h皟鐢ㄥ嚟鎹� + /// </summary> + /// <param name="userType"></param> + /// <returns></returns> + public async Task<string> GetAccessToken(EnumUserType userType) + { + var cacheKey = $"Wxmp|{userType}|AccessToken"; + var accessToken = await distributedCache.GetStringAsync(cacheKey); + if (accessToken.IsNull()) + { + var option = options.Value.Items.FirstOrDefault(it => it.Code == userType.ToString()); + if (option == null || option.AppId.IsNull() || option.AppSecret.IsNull()) + throw Oops.Oh(EnumErrorCodeType.s400, "鑾峰彇灏忕▼搴忔帴鍙h皟鐢ㄥ嚟鎹け璐ワ紝缂哄け閰嶇疆锛歐xmpOptions"); + var request = new WxmpGetAccessTokenRequest + { + Appid = option.AppId, + Secret = option.AppSecret, + }; + var response = await httpRemoteService.GetAsStringAsync("https://api.weixin.qq.com/cgi-bin/token", + builder => builder.WithQueryParameters(JsonObject.Parse(request.ToJson()))); + var callback = response.JsonTo<WxmpGetAccessTokenResponse>(); + if (callback == null && callback.AccessToken.IsNull()) + throw Oops.Oh(EnumErrorCodeType.s510, "鑾峰彇灏忕▼搴忔帴鍙h皟鐢ㄥ嚟鎹け璐�"); + accessToken = callback.AccessToken; + await distributedCache.SetStringAsync(cacheKey, accessToken, new DistributedCacheEntryOptions + { + AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(callback.ExpiresIn - 300) + }); + } + return accessToken; + } + + /// <summary> + /// 鑾峰彇灏忕▼搴忕爜 + /// </summary> + /// <param name="command"></param> + /// <returns></returns> + public async Task<string> GetQrCodeOssUrl(WxmpGetQrCodeCommand command) + { + var option = options.Value.Items.FirstOrDefault(it => it.Code == command.UserType.ToString()); + if (option == null || option.AppId.IsNull() || option.AppSecret.IsNull()) + throw Oops.Oh(EnumErrorCodeType.s400, "鑾峰彇灏忕▼搴忕爜澶辫触锛岀己澶遍厤缃細WxmpOptions"); + command.EnvVersion = option.EnvVersion; + var accessToken = await GetAccessToken(command.UserType); + var request = command.Adapt<WxmpGetQrCodeRequest>(); + var jsonContent = JsonConvert.SerializeObject(request, new JsonSerializerSettings + { + NullValueHandling = NullValueHandling.Ignore + }); + var response = await httpRemoteService.PostAsync("https://api.weixin.qq.com/wxa/getwxacodeunlimit", + builder => builder + .WithQueryParameter("access_token", accessToken) + .SetJsonContent(jsonContent)); + response.EnsureSuccessStatusCode(); + if (response.Content.Headers.ContentType.ToString() == "application/json; charset=UTF-8") + { + var jsonResult = await response.Content.ReadAsStringAsync(); + var callback = jsonResult.JsonTo<WxmpGetQrCodeResponse>(); + if (callback == null || callback.ErrorCode != 0) + throw Oops.Oh(EnumErrorCodeType.s510, $"鑾峰彇灏忕▼搴忕爜澶辫触锛歿callback.ErrorMessage}锛岃鑱旂郴绠$悊鍛�"); + } + var stream = await response.Content.ReadAsStreamAsync(); + var result = AliyunOSSUtils.Upload(command.OssScene, stream, command.OssFileName); + return result.Url; + } } } -- Gitblit v1.9.1