149 lines
5.2 KiB
C#
149 lines
5.2 KiB
C#
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
|
|
{
|
|
/// <summary>
|
|
/// 小程序帮助类
|
|
/// </summary>
|
|
/// <param name="appId"></param>
|
|
/// <param name="secret"></param>
|
|
/// <param name="database"></param>
|
|
/// <param name="_httpClientFactory"></param>
|
|
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<dynamic> 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<string> 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<Dictionary<string, object>> GetCurlData(string url)
|
|
{
|
|
using HttpClient client = _httpClientFactory.CreateClient();
|
|
var response = await client.GetStringAsync(url);
|
|
return JsonConvert.DeserializeObject<Dictionary<string, object>>(response);
|
|
}
|
|
|
|
// Helper method for POST requests
|
|
private async Task<Dictionary<string, object>> 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<Dictionary<string, object>>(result);
|
|
}
|
|
|
|
// Helper method for HTTP POST data
|
|
private async Task<string> 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<AccessToken>(json);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
private void SetConfig(AccessToken access)
|
|
{
|
|
var outTime = new TimeSpan(0, 0, 7000);
|
|
database.StringSet(key, JsonConvert.SerializeObject(access), outTime);
|
|
}
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
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()
|
|
{
|
|
|
|
}
|
|
}
|
|
}
|