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()
{
}
}
}