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