小程序环境配置
This commit is contained in:
parent
2e42fe76fa
commit
55e6fa71f3
@ -98,6 +98,8 @@
|
|||||||
},
|
},
|
||||||
// 微信小程序配置
|
// 微信小程序配置
|
||||||
"WeChat": {
|
"WeChat": {
|
||||||
|
// 小程序码版本:develop=开发版,trial=体验版,release=正式版;上线前请改为 release
|
||||||
|
"MiniProgramEnvVersion": "develop",
|
||||||
"AppId": "wxf5a3f98d44c3a563",
|
"AppId": "wxf5a3f98d44c3a563",
|
||||||
"Secret": "ef6d17e0419700c137e066aa3dce23ca"
|
"Secret": "ef6d17e0419700c137e066aa3dce23ca"
|
||||||
},
|
},
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
using System.Net.Http.Json;
|
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using EasyCaching.Core;
|
using EasyCaching.Core;
|
||||||
using Furion.DependencyInjection;
|
using Furion.DependencyInjection;
|
||||||
@ -41,30 +40,48 @@ public class WeChatMiniProgramCodeService : ITransient
|
|||||||
throw Oops.Bah("微信小程序配置不完整");
|
throw Oops.Bah("微信小程序配置不完整");
|
||||||
|
|
||||||
using var timeout = new CancellationTokenSource(TimeSpan.FromSeconds(15));
|
using var timeout = new CancellationTokenSource(TimeSpan.FromSeconds(15));
|
||||||
|
try
|
||||||
|
{
|
||||||
return await GenerateAsync(scene, page, width, false, timeout.Token);
|
return await GenerateAsync(scene, page, width, false, timeout.Token);
|
||||||
}
|
}
|
||||||
|
catch (OperationCanceledException) when (timeout.IsCancellationRequested)
|
||||||
|
{
|
||||||
|
_logger.LogError("WeChat mini program code request timed out after 15 seconds");
|
||||||
|
throw Oops.Bah("微信小程序码服务请求超时,请稍后重试");
|
||||||
|
}
|
||||||
|
catch (HttpRequestException exception)
|
||||||
|
{
|
||||||
|
_logger.LogError("WeChat mini program code network error: {ErrorType}, {ErrorMessage}",
|
||||||
|
exception.GetType().Name, exception.Message);
|
||||||
|
throw Oops.Bah("微信小程序码服务网络异常,请稍后重试");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private async Task<byte[]> GenerateAsync(string scene, string page, int width,
|
private async Task<byte[]> GenerateAsync(string scene, string page, int width,
|
||||||
bool forceRefreshToken, CancellationToken cancellationToken)
|
bool forceRefreshToken, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var accessToken = await GetAccessTokenAsync(forceRefreshToken, cancellationToken);
|
var accessToken = await GetAccessTokenAsync(forceRefreshToken, cancellationToken);
|
||||||
var client = _httpClientFactory.CreateClient();
|
var client = _httpClientFactory.CreateClient();
|
||||||
using var response = await client.PostAsJsonAsync(
|
var requestBody = JsonConvert.SerializeObject(new
|
||||||
$"https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token={Uri.EscapeDataString(accessToken)}",
|
|
||||||
new
|
|
||||||
{
|
{
|
||||||
scene,
|
scene,
|
||||||
page,
|
page,
|
||||||
width,
|
width,
|
||||||
check_path = true,
|
check_path = true,
|
||||||
env_version = NormalizeEnvVersion(_options.MiniProgramEnvVersion)
|
env_version = NormalizeEnvVersion(_options.MiniProgramEnvVersion)
|
||||||
}, cancellationToken);
|
});
|
||||||
|
using var requestContent = new StringContent(requestBody, Encoding.UTF8, "application/json");
|
||||||
|
using var response = await client.PostAsync(
|
||||||
|
$"https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token={Uri.EscapeDataString(accessToken)}",
|
||||||
|
requestContent, cancellationToken);
|
||||||
if (!response.IsSuccessStatusCode)
|
if (!response.IsSuccessStatusCode)
|
||||||
{
|
{
|
||||||
var errorBody = await response.Content.ReadAsStringAsync(cancellationToken);
|
var errorBody = await response.Content.ReadAsStringAsync(cancellationToken);
|
||||||
_logger.LogError("WeChat mini program code HTTP error: {StatusCode}, Body: {ErrorBody}",
|
_logger.LogError(
|
||||||
response.StatusCode, errorBody);
|
"WeChat mini program code HTTP error: {StatusCode}, Page: {Page}, EnvVersion: {EnvVersion}, Body: {ErrorBody}",
|
||||||
throw Oops.Bah("微信小程序码服务暂不可用,请检查微信接口白名单配置");
|
response.StatusCode, page, NormalizeEnvVersion(_options.MiniProgramEnvVersion), LimitLogContent(errorBody));
|
||||||
|
|
||||||
|
throw Oops.Bah("微信小程序码服务暂不可用,请稍后重试");
|
||||||
}
|
}
|
||||||
|
|
||||||
var bytes = await response.Content.ReadAsByteArrayAsync(cancellationToken);
|
var bytes = await response.Content.ReadAsByteArrayAsync(cancellationToken);
|
||||||
@ -89,7 +106,7 @@ public class WeChatMiniProgramCodeService : ITransient
|
|||||||
return await GenerateAsync(scene, page, width, true, cancellationToken);
|
return await GenerateAsync(scene, page, width, true, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
_logger.LogError("WeChat mini program code error: {Error}", errorJson);
|
_logger.LogError("WeChat mini program code error: {Error}", LimitLogContent(errorJson));
|
||||||
throw Oops.Bah("微信小程序码生成失败,请稍后重试");
|
throw Oops.Bah("微信小程序码生成失败,请稍后重试");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -109,15 +126,15 @@ public class WeChatMiniProgramCodeService : ITransient
|
|||||||
{
|
{
|
||||||
var errorBody = await response.Content.ReadAsStringAsync(cancellationToken);
|
var errorBody = await response.Content.ReadAsStringAsync(cancellationToken);
|
||||||
_logger.LogError("WeChat access token HTTP error: {StatusCode}, Body: {ErrorBody}",
|
_logger.LogError("WeChat access token HTTP error: {StatusCode}, Body: {ErrorBody}",
|
||||||
response.StatusCode, errorBody);
|
response.StatusCode, LimitLogContent(errorBody));
|
||||||
throw Oops.Bah("微信服务暂不可用,请检查微信接口白名单配置");
|
throw Oops.Bah("微信服务暂不可用,请稍后重试");
|
||||||
}
|
}
|
||||||
|
|
||||||
var json = await response.Content.ReadAsStringAsync(cancellationToken);
|
var json = await response.Content.ReadAsStringAsync(cancellationToken);
|
||||||
var token = JsonConvert.DeserializeObject<WeChatAccessTokenResponse>(json);
|
var token = JsonConvert.DeserializeObject<WeChatAccessTokenResponse>(json);
|
||||||
if (token == null || string.IsNullOrWhiteSpace(token.AccessToken))
|
if (token == null || string.IsNullOrWhiteSpace(token.AccessToken))
|
||||||
{
|
{
|
||||||
_logger.LogError("WeChat access token error: {Error}", json);
|
_logger.LogError("WeChat access token error: {Error}", LimitLogContent(json));
|
||||||
throw Oops.Bah("微信访问凭证获取失败,请检查小程序配置");
|
throw Oops.Bah("微信访问凭证获取失败,请检查小程序配置");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -129,13 +146,18 @@ public class WeChatMiniProgramCodeService : ITransient
|
|||||||
private static bool IsJpeg(byte[] bytes) => bytes.Length >= 3
|
private static bool IsJpeg(byte[] bytes) => bytes.Length >= 3
|
||||||
&& bytes[0] == 0xFF && bytes[1] == 0xD8 && bytes[2] == 0xFF;
|
&& bytes[0] == 0xFF && bytes[1] == 0xD8 && bytes[2] == 0xFF;
|
||||||
|
|
||||||
private static string NormalizeEnvVersion(string? envVersion) => envVersion?.ToLowerInvariant() switch
|
private static string NormalizeEnvVersion(string? envVersion) => envVersion?.Trim().ToLowerInvariant() switch
|
||||||
{
|
{
|
||||||
"develop" => "develop",
|
"develop" => "develop",
|
||||||
"trial" => "trial",
|
"trial" => "trial",
|
||||||
_ => "release"
|
null or "" or "release" => "release",
|
||||||
|
_ => throw Oops.Bah("微信小程序码版本配置无效,仅支持 develop、trial 或 release")
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private static string LimitLogContent(string content) => content.Length <= 4096
|
||||||
|
? content
|
||||||
|
: $"{content[..4096]}...(truncated)";
|
||||||
|
|
||||||
private sealed class WeChatAccessTokenResponse : WeChatApiError
|
private sealed class WeChatAccessTokenResponse : WeChatApiError
|
||||||
{
|
{
|
||||||
[JsonProperty("access_token")]
|
[JsonProperty("access_token")]
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user