using Newtonsoft.Json; using StackExchange.Redis; using System; using System.Collections.Generic; using System.Linq; using System.Net.Http; using System.Text; using System.Threading.Tasks; namespace HuanMeng.DotNetCore.WeChat { /// /// 小程序帮助类 /// /// /// /// /// public class MiniProgram(string appId, string secret, IDatabase database, IHttpClientFactory? _httpClientFactory) { public string AppId { get; set; } = appId; string key = $"WeChat:{appId}"; // Method to get user's OpenID public async Task<(string openId, string unionid, string session_key)> GetOpenid(string code) { string url = $"https://api.weixin.qq.com/sns/jscode2session?appid={appId}&secret={secret}&js_code={code}&grant_type=authorization_code"; var resUserInfo = await GetCurlData(url); if (resUserInfo.ContainsKey("errcode")) { return (null, null, null); } string openid = resUserInfo.GetValueOrDefault("openid")?.ToString() ?? ""; string unionid = resUserInfo.GetValueOrDefault("unionid")?.ToString() ?? ""; string session_key = resUserInfo.GetValueOrDefault("session_key")?.ToString() ?? ""; return new(openid, unionid, session_key); } // Get user info based on access token and openid public async Task GetUserInfoAsync(string openid) { var accessToken = await GetAccessToken(); string url = $"https://api.weixin.qq.com/sns/userinfo?access_token={accessToken}&openid={openid}&lang=zh_CN"; var response = await GetCurlData(url); return response; } public async Task GetAccessToken() { var accessTokenInfo = GetConfig(); if (accessTokenInfo != null) { return accessTokenInfo?.Access_token; } else { string url = $"https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={appId}&secret={secret}"; var resAccessToken = await GetCurlData(url); if (resAccessToken.ContainsKey("errcode")) { throw new Exception("获取微信token失败"); } string accessToken = resAccessToken["access_token"].ToString(); int expiresIn = Convert.ToInt32(resAccessToken["expires_in"]); long accessTokenTime = DateTimeOffset.UtcNow.ToUnixTimeSeconds() + expiresIn; var data = new AccessToken(accessToken, accessTokenTime); SetConfig(data); return accessToken; } } // Helper method for GET requests private async Task> GetCurlData(string url) { using HttpClient client = _httpClientFactory.CreateClient(); var response = await client.GetStringAsync(url); return JsonConvert.DeserializeObject>(response); } // Helper method for POST requests private async Task> PostCurlData(string url, object data) { using HttpClient client = _httpClientFactory.CreateClient(); var json = JsonConvert.SerializeObject(data); var content = new StringContent(json, Encoding.UTF8, "application/json"); var response = await client.PostAsync(url, content); var result = await response.Content.ReadAsStringAsync(); return JsonConvert.DeserializeObject>(result); } // Helper method for HTTP POST data private async Task HttpPostData(string url, object data) { using HttpClient client = _httpClientFactory.CreateClient(); var json = JsonConvert.SerializeObject(data); var content = new StringContent(json, Encoding.UTF8, "application/json"); var response = await client.PostAsync(url, content); return await response.Content.ReadAsStringAsync(); } private AccessToken? GetConfig() { var json = database.StringGet(key); if (!string.IsNullOrEmpty(json)) { return JsonConvert.DeserializeObject(json); } return null; } private void SetConfig(AccessToken access) { var outTime = new TimeSpan(0, 0, 7000); database.StringSet(key, JsonConvert.SerializeObject(access), outTime); } } /// /// /// public class AccessToken { public string? Access_token { get; } public long Access_token_time { get; } public AccessToken(string? access_token, long access_token_time) { Access_token = access_token; Access_token_time = access_token_time; } public AccessToken() { } } }