WechatSharp/Services/WeChatUserInfoService.cs

102 lines
3.5 KiB
C#

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<WeChatUserInfoService> _logger;
private readonly ConcurrentDictionary<string,WeChatUserInfo> weChatUserInfos = new();
private readonly ConcurrentDictionary<string,WeChatUserInfo> codeBasedWeChatUserInfos = new();
public WeChatUserInfoService(HttpClient httpClient, WeChatAccessTokenService accessTokenService, IWeChatSettings weChatSettings, ILogger<WeChatUserInfoService> logger)
{
_httpClient = httpClient;
this.accessTokenService = accessTokenService;
_weChatSettings = weChatSettings;
_logger = logger;
}
public List<WeChatUserInfo> GetCachedWeChatUserInfos()
{
return weChatUserInfos.Values.ToList();
}
public async Task<WeChatUserInfo> 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<JObject>(json)!;
if (jObject.TryGetValue("errcode", out var value))
{
var ErrorMessage = jObject["errmsg"]!.ToObject<string>();
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<string>()!;
userInfo = await GetUserInfoAsync(openId,accessToken.ToObject<string>()!);
_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<WeChatUserInfo> 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<WeChatUserInfo> 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<JObject>(json)!;
if (jObject.ContainsKey("errcode"))
{
Console.WriteLine(jObject);
}
var weChatUserInfo = JsonConvert.DeserializeObject<WeChatUserInfo>(json);
return weChatUserInfo;
}
}