using LifePayment.Domain.Shared;
|
using Microsoft.Extensions.Caching.Distributed;
|
using Microsoft.Extensions.Options;
|
using Newtonsoft.Json;
|
using System;
|
using System.IO;
|
using System.Net.Http;
|
using System.Security.Cryptography;
|
using System.Text;
|
using System.Threading.Tasks;
|
using Volo.Abp;
|
using Volo.Abp.Caching;
|
using ZeroD.Util;
|
|
namespace LifePayment.Domain
|
{
|
public class WxManager : IWxManager
|
{
|
private readonly WxMiniAppOption _wxOptions;
|
private readonly InformationOption _informationOption;
|
private readonly WxMatchMakingMiniAppOption _wxMatchMakingMiniAppOption;
|
private readonly ICommonManager _commonManager;
|
private readonly IHttpClientFactory _httpClientFactory;
|
private readonly IDistributedCache<string> _distributedCache;
|
|
public WxManager(
|
ICommonManager commonManager,
|
IHttpClientFactory httpClientFactory,
|
IDistributedCache<string> distributedCache,
|
IOptionsMonitor<WxMiniAppOption> wxOptionsMonitor,
|
IOptionsMonitor<InformationOption> informationOptionMonitor,
|
IOptionsMonitor<WxMatchMakingMiniAppOption> wxMatchMakingMiniAppOptionMonitor)
|
{
|
_commonManager = commonManager;
|
_distributedCache = distributedCache;
|
_httpClientFactory = httpClientFactory;
|
_wxOptions = wxOptionsMonitor.CurrentValue;
|
_informationOption = informationOptionMonitor.CurrentValue;
|
_wxMatchMakingMiniAppOption = wxMatchMakingMiniAppOptionMonitor.CurrentValue;
|
}
|
|
public async Task<string> GetWxMiniAccessToken()
|
{
|
var result = await _distributedCache.GetAsync(LifePaymentConstant.小程序Token缓存key);
|
if (result != null)
|
{
|
return result;
|
}
|
|
var client = _httpClientFactory.CreateClient(LifePaymentConstant.WeChatHttpClientName);
|
var url = $"{_wxOptions.Url}{string.Format(LifePaymentConstant.微信小程序获取Token, _wxOptions.AppId, _wxOptions.Secret)}";
|
var responseMessage = await client.GetAsync(url);
|
var str = await responseMessage.Content.ReadAsStringAsync();
|
var res = JsonConvert.DeserializeObject<WxMiniTokenInfo>(str);
|
if (res == null || res.AccessToken.IsNullOrEmpty() || res.ExpiresIn == default)
|
{
|
throw new UserFriendlyException("获取小程序token失败");
|
}
|
|
await _distributedCache.SetAsync(LifePaymentConstant.小程序Token缓存key, res.AccessToken, new DistributedCacheEntryOptions
|
{
|
AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(res.ExpiresIn - 360),
|
});
|
return res.AccessToken;
|
}
|
|
public async Task<string> GetWxCgiAccessToken()
|
{
|
var result = await _distributedCache.GetAsync(LifePaymentConstant.微信公众号Token缓存key);
|
if (result != null)
|
{
|
return result;
|
}
|
|
var client = _httpClientFactory.CreateClient(LifePaymentConstant.WeChatHttpClientName);
|
var url = $"{_informationOption.RequestUrl}{string.Format(LifePaymentConstant.微信小程序获取Token, _informationOption.AppId, _informationOption.AppSecret)}";
|
var responseMessage = await client.GetAsync(url);
|
var str = await responseMessage.Content.ReadAsStringAsync();
|
var res = JsonConvert.DeserializeObject<WxMiniTokenInfo>(str);
|
if (res == null || res.AccessToken.IsNullOrEmpty() || res.ExpiresIn == default)
|
{
|
throw new UserFriendlyException("获取小程序token失败");
|
}
|
|
await _distributedCache.SetAsync(LifePaymentConstant.微信公众号Token缓存key, res.AccessToken, new DistributedCacheEntryOptions
|
{
|
AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(res.ExpiresIn - 360),
|
});
|
return res.AccessToken;
|
}
|
|
public async Task<string> CreateQrCodeUrl(string name, CreateQrCodeInput input)
|
{
|
var res = await CreateQrCode(input);
|
var reslut = _commonManager.GetOssUrl(LifePaymentConstant.扫码登录二维码路径, name, res, "png");
|
return reslut;
|
}
|
|
public async Task<byte[]> CreateQrCode(CreateQrCodeInput input)
|
{
|
var token = await GetWxMiniAccessToken();
|
string url = $"{_informationOption.RequestUrl}{string.Format(LifePaymentConstant.微信小程序创建二维码, token)}"; ;
|
return await _commonManager.PostAsync<byte[]>(url, new
|
{
|
page = input.Page,
|
scene = input.Scene,
|
env_version = input.EnvVersion,
|
width = input.Width,
|
check_path = input.CheckPath,
|
});
|
}
|
|
public async Task<WxMiniAppIndentity> GetWxIndentity(string code, WxMiniAppEnum wxMiniApp)
|
{
|
var appInfo = GetAppInfoByEnum(wxMiniApp);
|
var url = $"{appInfo.Url}{string.Format(LifePaymentConstant.微信小程序身份会话信息, appInfo.AppId, appInfo.Secret, code)}";
|
var result = await _commonManager.PostAsync<WxMiniAppIndentity>(url, null);
|
return result;
|
}
|
|
|
public async Task<WxMiniAppIndentity> GetWxOauth2AccessToken(string code)
|
{
|
var url = $"{_informationOption.RequestUrl}{string.Format(LifePaymentConstant.微信公众号获取access_token, _informationOption.AppId, _informationOption.AppSecret, code)}";
|
var result = await _commonManager.PostAsync<WxMiniAppIndentity>(url, null);
|
return result;
|
}
|
|
public async Task<GetCgiWritingResponse> GetWxPublishWriting()
|
{
|
var token = await GetWxCgiAccessToken();
|
var input = new GetCgiWritingInput();
|
input.AccessToken = token;
|
var url = $"{_wxOptions.Url}{string.Format(LifePaymentConstant.微信接口获取公众号文章, token)}";
|
var requestContent = new StringContent(JsonString.Object2Json(input), Encoding.UTF8, "application/json");
|
var client = _httpClientFactory.CreateClient(LifePaymentConstant.WeChatHttpClientName);
|
var responseMessage = await client.PostAsync(url, requestContent);
|
var str = await responseMessage.Content.ReadAsStringAsync();
|
var res = JsonConvert.DeserializeObject<GetCgiWritingResponse>(str);
|
return res;
|
}
|
|
public string GetPhoneNumber(string encryptedDataStr, string iv, string sessionKey)
|
{
|
return GetUserInfo(encryptedDataStr, iv, sessionKey)?.PhoneNumber;
|
}
|
|
public WxMiniAppUserInfo GetUserInfo(string encryptedDataStr, string iv, string sessionKey)
|
{
|
var result = string.Empty;
|
RijndaelManaged rijalg = new RijndaelManaged();
|
rijalg.KeySize = 128;
|
rijalg.Padding = PaddingMode.PKCS7;
|
rijalg.Mode = CipherMode.CBC;
|
rijalg.Key = Convert.FromBase64String(sessionKey);
|
rijalg.IV = Convert.FromBase64String(iv);
|
byte[] encryptedData = Convert.FromBase64String(encryptedDataStr);
|
ICryptoTransform decryptor = rijalg.CreateDecryptor(rijalg.Key, rijalg.IV);
|
using (MemoryStream msDecrypt = new MemoryStream(encryptedData))
|
{
|
using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
|
{
|
using (StreamReader srDecrypt = new StreamReader(csDecrypt))
|
{
|
result = srDecrypt.ReadToEnd();
|
}
|
}
|
}
|
|
return JsonConvert.DeserializeObject<WxMiniAppUserInfo>(result);
|
}
|
|
private (string Url, string AppId, string Secret) GetAppInfoByEnum(WxMiniAppEnum wxMiniApp)
|
{
|
return wxMiniApp switch
|
{
|
WxMiniAppEnum.行业资讯 => (_wxOptions.Url, _wxOptions.AppId, _wxOptions.Secret),
|
WxMiniAppEnum.人单合一 => (_wxMatchMakingMiniAppOption.Url, _wxMatchMakingMiniAppOption.AppId, _wxMatchMakingMiniAppOption.Secret),
|
WxMiniAppEnum.生活缴费 => (_wxMatchMakingMiniAppOption.Url, _wxMatchMakingMiniAppOption.AppId, _wxMatchMakingMiniAppOption.Secret),
|
_ => throw new UserFriendlyException("存在未实现的WxMiniAppEnum"),
|
};
|
}
|
}
|
}
|