小程序环境配置

This commit is contained in:
马梓彭 2026-09-17 11:48:14 +08:00
parent 2e42fe76fa
commit 55e6fa71f3
2 changed files with 45 additions and 21 deletions

View File

@ -98,6 +98,8 @@
}, },
// 微信小程序配置 // 微信小程序配置
"WeChat": { "WeChat": {
// 小程序码版本:develop=开发版,trial=体验版,release=正式版;上线前请改为 release
"MiniProgramEnvVersion": "develop",
"AppId": "wxf5a3f98d44c3a563", "AppId": "wxf5a3f98d44c3a563",
"Secret": "ef6d17e0419700c137e066aa3dce23ca" "Secret": "ef6d17e0419700c137e066aa3dce23ca"
}, },
@ -172,4 +174,4 @@
"ScoringUnitRoleId": 1003, "ScoringUnitRoleId": 1003,
"HiddenMenuIds": [2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009] "HiddenMenuIds": [2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009]
} }
} }

View File

@ -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,7 +40,21 @@ 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));
return await GenerateAsync(scene, page, width, false, timeout.Token); try
{
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,
@ -49,22 +62,26 @@ public class WeChatMiniProgramCodeService : ITransient
{ {
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
{
scene,
page,
width,
check_path = true,
env_version = NormalizeEnvVersion(_options.MiniProgramEnvVersion)
});
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)}", $"https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token={Uri.EscapeDataString(accessToken)}",
new requestContent, cancellationToken);
{
scene,
page,
width,
check_path = true,
env_version = NormalizeEnvVersion(_options.MiniProgramEnvVersion)
}, 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")]