using System.Collections.Concurrent; using System.Diagnostics; using System.Numerics; using Cysharp.Threading.Tasks; using Microsoft.Extensions.Logging; using Microsoft.VisualBasic; using Newtonsoft.Json; using Newtonsoft.Json.Linq; namespace WeChatSharp.Services; public class WeChatUserInfoService { private readonly HttpClient _httpClient; private readonly WeChatAccessTokenService accessTokenService; private readonly IWeChatSettings _weChatSettings; private readonly ILogger _logger; private readonly ConcurrentDictionary weChatUserInfos = new(); private readonly ConcurrentDictionary codeBasedWeChatUserInfos = new(); public WeChatUserInfoService(HttpClient httpClient, WeChatAccessTokenService accessTokenService, IWeChatSettings weChatSettings, ILogger logger) { _httpClient = httpClient; this.accessTokenService = accessTokenService; _weChatSettings = weChatSettings; _logger = logger; } public List GetCachedWeChatUserInfos() { return weChatUserInfos.Values.ToList(); } public async Task GetUserInfoByCode(string code) { if (codeBasedWeChatUserInfos.TryGetValue(code, out var userInfo)) return userInfo; var json = await _httpClient.GetStringAsync( $""" https://api.weixin.qq.com/sns/oauth2/access_token?appid={_weChatSettings.AppId}&secret={_weChatSettings.AppSecret}&code={code}&grant_type=authorization_code """); var jObject = JsonConvert.DeserializeObject(json)!; if (jObject.TryGetValue("errcode", out var value)) { var ErrorMessage = jObject["errmsg"]!.ToObject(); if (codeBasedWeChatUserInfos.TryGetValue(code, out userInfo)) { return userInfo; } throw new InvalidOperationException(ErrorMessage); } if (jObject.TryGetValue("openid", out var _token) && jObject.TryGetValue("access_token",out var accessToken)) { var openId = _token.ToObject()!; userInfo = await GetUserInfoAsync(openId,accessToken.ToObject()!); _logger.LogInformation($"已经获取到了{code}的用户:{userInfo.OpenId}");; _logger.LogInformation(json); codeBasedWeChatUserInfos.TryAdd(code, userInfo); return userInfo; } _logger.LogWarning("没有找到OpenId,获取的数据为;"); _logger.LogWarning(json); throw new InvalidOperationException("无效的Code"); } public async Task GetUserInfoAsync(string openId,string accessToken=default!) { if(weChatUserInfos.TryGetValue(openId,out var userInfo)) return userInfo; userInfo =await GetWeChatUserInfoFromServer(openId,accessToken); weChatUserInfos.TryAdd(openId,userInfo); return userInfo; } private async Task GetWeChatUserInfoFromServer(string openId,string _accessToken=default!) { var accessToken = _accessToken; string url; if (string.IsNullOrEmpty(accessToken)) { accessToken = await accessTokenService.GetAccessTokenAsync(); url = $"https://api.weixin.qq.com/cgi-bin/user/info?access_token={accessToken}&openid={openId}&lang=zh_CN"; } else { url = $"https://api.weixin.qq.com/sns/userinfo?access_token={accessToken}&openid={openId}&lang=zh_CN"; } var json = await _httpClient.GetStringAsync(url); var jObject = JsonConvert.DeserializeObject(json)!; if (jObject.ContainsKey("errcode")) { Console.WriteLine(jObject); } var weChatUserInfo = JsonConvert.DeserializeObject(json); return weChatUserInfo; } }