102 lines
3.5 KiB
C#
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;
|
|
}
|
|
} |