This commit is contained in:
zpc 2026-01-27 13:18:10 +08:00
parent 53a61f6298
commit 11ee8d963c
4 changed files with 118 additions and 157 deletions

View File

@ -57,11 +57,6 @@ try
builder.Configuration.GetSection("JwtSettings").Bind(jwtSettings);
builder.Services.AddSingleton(jwtSettings);
// 配置微信设置
var wechatSettings = new WechatSettings();
builder.Configuration.GetSection("WechatSettings").Bind(wechatSettings);
builder.Services.AddSingleton(wechatSettings);
// 配置高德地图设置
var amapSettings = new AmapSettings();
builder.Configuration.GetSection("AmapSettings").Bind(amapSettings);

View File

@ -3,10 +3,6 @@
"DefaultConnection": "Server=192.168.195.15;uid=sa;pwd=Dbt@com@123;Database=honey_box;MultipleActiveResultSets=true;pooling=true;min pool size=5;max pool size=32767;connect timeout=20;Encrypt=True;TrustServerCertificate=True;",
"Redis": "192.168.195.15:6379,abortConnect=false,connectTimeout=5000"
},
"WechatSettings": {
"AppId": "",
"AppSecret": ""
},
"WechatPaySettings": {
"DefaultMerchant": {
"Name": "默认商户",

View File

@ -17,7 +17,6 @@ public class WechatService : IWechatService
{
private readonly HttpClient _httpClient;
private readonly ILogger<WechatService> _logger;
private readonly WechatSettings _wechatSettings;
private readonly WechatPaySettings _wechatPaySettings;
private readonly IRedisService _redisService;
private readonly HoneyBoxDbContext _dbContext;
@ -33,14 +32,12 @@ public class WechatService : IWechatService
public WechatService(
HttpClient httpClient,
ILogger<WechatService> logger,
WechatSettings wechatSettings,
IOptions<WechatPaySettings> wechatPaySettings,
IRedisService redisService,
HoneyBoxDbContext dbContext)
{
_httpClient = httpClient ?? throw new ArgumentNullException(nameof(httpClient));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
_wechatSettings = wechatSettings ?? throw new ArgumentNullException(nameof(wechatSettings));
_wechatPaySettings = wechatPaySettings?.Value ?? throw new ArgumentNullException(nameof(wechatPaySettings));
_redisService = redisService ?? throw new ArgumentNullException(nameof(redisService));
_dbContext = dbContext ?? throw new ArgumentNullException(nameof(dbContext));
@ -67,8 +64,18 @@ public class WechatService : IWechatService
{
// 从数据库获取微信配置
var wechatConfig = await GetWechatSettingFromDbAsync();
var appId = wechatConfig?.AppId ?? _wechatSettings.AppId;
var appSecret = wechatConfig?.AppSecret ?? _wechatSettings.AppSecret;
if (wechatConfig == null)
{
_logger.LogError("[微信登录] 未找到小程序配置,请在后台管理系统中配置 miniprogram_setting");
return new WechatAuthResult
{
Success = false,
ErrorMessage = "小程序配置未设置,请联系管理员"
};
}
var appId = wechatConfig.AppId;
var appSecret = wechatConfig.AppSecret;
// 记录配置信息(脱敏)
var maskedAppId = appId?.Length > 8
@ -77,8 +84,8 @@ public class WechatService : IWechatService
var maskedSecret = string.IsNullOrEmpty(appSecret)
? "未配置"
: $"{appSecret.Substring(0, 4)}****";
_logger.LogInformation("[微信登录] 配置信息: AppId={AppId}, AppSecret={AppSecret}, 来源={Source}",
maskedAppId, maskedSecret, wechatConfig != null ? "数据库" : "appsettings");
_logger.LogInformation("[微信登录] 配置信息: AppId={AppId}, AppSecret={AppSecret}, 来源=数据库",
maskedAppId, maskedSecret);
var url = $"{WechatCodeToSessionUrl}?appid={appId}&secret={appSecret}&js_code={code}&grant_type=authorization_code";
@ -299,15 +306,23 @@ public class WechatService : IWechatService
/// <summary>
/// 获取小程序接口调用凭证access_token
/// </summary>
/// <param name="appId">小程序AppId可选不传则使用默认配置)</param>
/// <param name="appId">小程序AppId可选不传则使用数据库默认配置)</param>
/// <returns>access_token失败返回null</returns>
public async Task<string?> GetAccessTokenAsync(string? appId = null)
{
try
{
// 从数据库获取配置
var wechatConfig = await GetWechatSettingFromDbAsync();
if (wechatConfig == null)
{
_logger.LogError("无法获取access_token未找到小程序配置请在后台管理系统中配置 miniprogram_setting");
return null;
}
// 确定使用哪个AppId和AppSecret
var targetAppId = appId ?? _wechatSettings.AppId;
var targetAppSecret = GetAppSecretByAppId(targetAppId);
var targetAppId = appId ?? wechatConfig.AppId;
var targetAppSecret = await GetAppSecretByAppIdAsync(targetAppId);
if (string.IsNullOrEmpty(targetAppId) || string.IsNullOrEmpty(targetAppSecret))
{
@ -385,14 +400,15 @@ public class WechatService : IWechatService
}
/// <summary>
/// 根据AppId获取对应的AppSecret
/// 根据AppId获取对应的AppSecret(异步版本,从数据库读取)
/// </summary>
private string GetAppSecretByAppId(string appId)
private async Task<string> GetAppSecretByAppIdAsync(string appId)
{
// 首先检查默认配置
if (_wechatSettings.AppId == appId)
// 从数据库获取配置
var wechatConfig = await GetWechatSettingFromDbAsync();
if (wechatConfig != null && wechatConfig.AppId == appId)
{
return _wechatSettings.AppSecret;
return wechatConfig.AppSecret;
}
// 从小程序配置列表中查找
@ -402,9 +418,9 @@ public class WechatService : IWechatService
return miniprogram.AppSecret;
}
// 如果都没找到,返回默认配置的AppSecret
_logger.LogWarning("未找到AppId {AppId} 的配置,使用默认AppSecret", appId);
return _wechatSettings.AppSecret;
// 如果都没找到,返回数据库默认配置的AppSecret
_logger.LogWarning("未找到AppId {AppId} 的配置,使用数据库默认配置", appId);
return wechatConfig?.AppSecret ?? string.Empty;
}
/// <summary>
@ -598,85 +614,66 @@ public class WechatService : IWechatService
/// <summary>
/// 从数据库获取微信小程序配置
/// 优先从 miniprogram_setting 读取默认小程序配置,如果没有则回退到 wechat_setting
/// 仅从 miniprogram_setting 读取,无配置则返回 null
/// </summary>
private async Task<WechatSettings?> GetWechatSettingFromDbAsync()
{
try
{
// 1. 优先从 miniprogram_setting 读取默认小程序配置
// 从 miniprogram_setting 读取小程序配置
var miniprogramConfig = await _dbContext.Configs
.Where(c => c.ConfigKey == "miniprogram_setting")
.Select(c => c.ConfigValue)
.FirstOrDefaultAsync();
if (!string.IsNullOrEmpty(miniprogramConfig))
if (string.IsNullOrEmpty(miniprogramConfig))
{
var config = JsonSerializer.Deserialize<JsonElement>(miniprogramConfig);
_logger.LogWarning("[微信配置] 数据库中未找到 miniprogram_setting 配置");
return null;
}
var config = JsonSerializer.Deserialize<JsonElement>(miniprogramConfig);
if (!config.TryGetProperty("miniprograms", out var miniprograms) || miniprograms.ValueKind != JsonValueKind.Array)
{
_logger.LogWarning("[微信配置] miniprogram_setting 配置格式错误,缺少 miniprograms 数组");
return null;
}
// 查找默认小程序配置 (is_default = 1)
foreach (var mp in miniprograms.EnumerateArray())
{
var isDefault = mp.TryGetProperty("is_default", out var isDefaultProp) &&
(isDefaultProp.ValueKind == JsonValueKind.Number ? isDefaultProp.GetInt32() == 1 : isDefaultProp.GetString() == "1");
if (config.TryGetProperty("miniprograms", out var miniprograms) && miniprograms.ValueKind == JsonValueKind.Array)
if (isDefault)
{
// 查找默认小程序配置 (is_default = 1)
foreach (var mp in miniprograms.EnumerateArray())
{
var isDefault = mp.TryGetProperty("is_default", out var isDefaultProp) &&
(isDefaultProp.ValueKind == JsonValueKind.Number ? isDefaultProp.GetInt32() == 1 : isDefaultProp.GetString() == "1");
if (isDefault)
{
var appId = mp.TryGetProperty("appid", out var appIdProp) ? appIdProp.GetString() : null;
var appSecret = mp.TryGetProperty("appsecret", out var appSecretProp) ? appSecretProp.GetString() : null;
var appId = mp.TryGetProperty("appid", out var appIdProp) ? appIdProp.GetString() : null;
var appSecret = mp.TryGetProperty("appsecret", out var appSecretProp) ? appSecretProp.GetString() : null;
if (!string.IsNullOrEmpty(appId) && !string.IsNullOrEmpty(appSecret))
{
_logger.LogDebug("[微信配置] 从 miniprogram_setting 读取默认小程序配置: AppId={AppId}",
appId.Length > 8 ? $"{appId.Substring(0, 4)}****{appId.Substring(appId.Length - 4)}" : appId);
return new WechatSettings
{
AppId = appId,
AppSecret = appSecret
};
}
}
}
// 如果没有默认配置,使用第一个小程序配置
var firstMp = miniprograms.EnumerateArray().FirstOrDefault();
if (firstMp.ValueKind == JsonValueKind.Object)
if (!string.IsNullOrEmpty(appId) && !string.IsNullOrEmpty(appSecret))
{
var appId = firstMp.TryGetProperty("appid", out var appIdProp) ? appIdProp.GetString() : null;
var appSecret = firstMp.TryGetProperty("appsecret", out var appSecretProp) ? appSecretProp.GetString() : null;
if (!string.IsNullOrEmpty(appId) && !string.IsNullOrEmpty(appSecret))
_logger.LogDebug("[微信配置] 从 miniprogram_setting 读取默认小程序配置: AppId={AppId}",
appId.Length > 8 ? $"{appId.Substring(0, 4)}****{appId.Substring(appId.Length - 4)}" : appId);
return new WechatSettings
{
_logger.LogDebug("[微信配置] 从 miniprogram_setting 读取第一个小程序配置: AppId={AppId}",
appId.Length > 8 ? $"{appId.Substring(0, 4)}****{appId.Substring(appId.Length - 4)}" : appId);
return new WechatSettings
{
AppId = appId,
AppSecret = appSecret
};
}
AppId = appId,
AppSecret = appSecret
};
}
}
}
// 2. 回退到 wechat_setting旧版单一配置
var wechatSettingConfig = await _dbContext.Configs
.Where(c => c.ConfigKey == "wechat_setting")
.Select(c => c.ConfigValue)
.FirstOrDefaultAsync();
if (!string.IsNullOrEmpty(wechatSettingConfig))
// 如果没有默认配置,使用第一个小程序配置
var firstMp = miniprograms.EnumerateArray().FirstOrDefault();
if (firstMp.ValueKind == JsonValueKind.Object)
{
var config = JsonSerializer.Deserialize<JsonElement>(wechatSettingConfig);
var appId = config.TryGetProperty("appid", out var appIdProp) ? appIdProp.GetString() : null;
var appSecret = config.TryGetProperty("appSecret", out var appSecretProp) ? appSecretProp.GetString() : null;
var appId = firstMp.TryGetProperty("appid", out var appIdProp) ? appIdProp.GetString() : null;
var appSecret = firstMp.TryGetProperty("appsecret", out var appSecretProp) ? appSecretProp.GetString() : null;
if (!string.IsNullOrEmpty(appId) && !string.IsNullOrEmpty(appSecret))
{
_logger.LogDebug("[微信配置] 从 wechat_setting 读取配置: AppId={AppId}",
_logger.LogDebug("[微信配置] 从 miniprogram_setting 读取第一个小程序配置: AppId={AppId}",
appId.Length > 8 ? $"{appId.Substring(0, 4)}****{appId.Substring(appId.Length - 4)}" : appId);
return new WechatSettings
{
@ -686,102 +683,76 @@ public class WechatService : IWechatService
}
}
_logger.LogDebug("[微信配置] 数据库中未找到有效的微信配置");
_logger.LogWarning("[微信配置] miniprogram_setting 中未找到有效的小程序配置");
return null;
}
catch (Exception ex)
{
_logger.LogWarning(ex, "[微信配置] 从数据库读取配置失败");
_logger.LogError(ex, "[微信配置] 从数据库读取配置失败");
return null;
}
return null;
}
/// <summary>
/// 获取商户配置(优先从数据库读取)
/// 获取商户配置(从数据库读取)
/// </summary>
private async Task<WechatPayMerchantConfig?> GetMerchantConfigAsync()
{
try
{
// 1. 尝试从数据库读取 weixinpay 配置
// 从数据库读取 weixinpay 配置
var weixinpayConfig = await _dbContext.Configs
.Where(c => c.ConfigKey == "weixinpay")
.Select(c => c.ConfigValue)
.FirstOrDefaultAsync();
if (!string.IsNullOrEmpty(weixinpayConfig))
if (string.IsNullOrEmpty(weixinpayConfig))
{
var config = JsonSerializer.Deserialize<JsonElement>(weixinpayConfig);
var mchId = config.TryGetProperty("mch_id", out var mchIdProp) ? mchIdProp.GetString() : null;
var appId = config.TryGetProperty("appid", out var appIdProp) ? appIdProp.GetString() : null;
var key = config.TryGetProperty("keys", out var keysProp) ? keysProp.GetString() : null;
if (!string.IsNullOrEmpty(mchId) && !string.IsNullOrEmpty(key))
{
// 如果 weixinpay 中没有 appid尝试从 wechat_setting 获取
if (string.IsNullOrEmpty(appId))
{
var wechatSettingConfig = await _dbContext.Configs
.Where(c => c.ConfigKey == "wechat_setting")
.Select(c => c.ConfigValue)
.FirstOrDefaultAsync();
if (!string.IsNullOrEmpty(wechatSettingConfig))
{
var wechatSetting = JsonSerializer.Deserialize<JsonElement>(wechatSettingConfig);
appId = wechatSetting.TryGetProperty("appid", out var wechatAppIdProp) ? wechatAppIdProp.GetString() : null;
}
}
// 如果还是没有 appid使用 appsettings.json 中的配置
if (string.IsNullOrEmpty(appId))
{
appId = _wechatSettings.AppId;
}
_logger.LogInformation("[微信支付] 从数据库读取配置: MchId={MchId}, AppId={AppId}", mchId, appId);
return new WechatPayMerchantConfig
{
Name = "数据库配置",
MchId = mchId,
AppId = appId ?? string.Empty,
Key = key,
OrderPrefix = "MYH",
Weight = 1
};
}
_logger.LogError("[微信支付] 数据库中未找到 weixinpay 配置");
return null;
}
_logger.LogWarning("[微信支付] 数据库中未找到有效的微信支付配置,使用 appsettings.json 配置");
var config = JsonSerializer.Deserialize<JsonElement>(weixinpayConfig);
var mchId = config.TryGetProperty("mch_id", out var mchIdProp) ? mchIdProp.GetString() : null;
var appId = config.TryGetProperty("appid", out var appIdProp) ? appIdProp.GetString() : null;
var key = config.TryGetProperty("keys", out var keysProp) ? keysProp.GetString() : null;
if (string.IsNullOrEmpty(mchId) || string.IsNullOrEmpty(key))
{
_logger.LogError("[微信支付] weixinpay 配置不完整,缺少 mch_id 或 keys");
return null;
}
// 如果 weixinpay 中没有 appid从 miniprogram_setting 获取
if (string.IsNullOrEmpty(appId))
{
var wechatConfig = await GetWechatSettingFromDbAsync();
appId = wechatConfig?.AppId;
}
if (string.IsNullOrEmpty(appId))
{
_logger.LogError("[微信支付] 未找到有效的 AppId 配置");
return null;
}
_logger.LogInformation("[微信支付] 从数据库读取配置: MchId={MchId}, AppId={AppId}", mchId, appId);
return new WechatPayMerchantConfig
{
Name = "数据库配置",
MchId = mchId,
AppId = appId,
Key = key,
OrderPrefix = "MYH",
Weight = 1
};
}
catch (Exception ex)
{
_logger.LogWarning(ex, "[微信支付] 从数据库读取配置失败,使用 appsettings.json 配置");
_logger.LogError(ex, "[微信支付] 从数据库读取配置失败");
return null;
}
// 2. 回退到 appsettings.json 配置
if (!string.IsNullOrEmpty(_wechatPaySettings.DefaultMerchant?.MchId))
{
return _wechatPaySettings.DefaultMerchant;
}
return _wechatPaySettings.Merchants.FirstOrDefault();
}
/// <summary>
/// 获取商户配置(同步版本,用于兼容)
/// </summary>
private WechatPayMerchantConfig? GetMerchantConfig()
{
// 优先使用 appsettings.json 中的默认商户配置
if (!string.IsNullOrEmpty(_wechatPaySettings.DefaultMerchant?.MchId))
{
return _wechatPaySettings.DefaultMerchant;
}
// 从商户列表中获取第一个
return _wechatPaySettings.Merchants.FirstOrDefault();
}
/// <summary>

View File

@ -26,11 +26,10 @@ public class ServiceModule : Module
{
var httpClientFactory = c.Resolve<System.Net.Http.IHttpClientFactory>();
var logger = c.Resolve<ILogger<WechatService>>();
var wechatSettings = c.Resolve<WechatSettings>();
var wechatPaySettings = c.Resolve<Microsoft.Extensions.Options.IOptions<WechatPaySettings>>();
var redisService = c.Resolve<IRedisService>();
var dbContext = c.Resolve<HoneyBoxDbContext>();
return new WechatService(httpClientFactory.CreateClient(), logger, wechatSettings, wechatPaySettings, redisService, dbContext);
return new WechatService(httpClientFactory.CreateClient(), logger, wechatPaySettings, redisService, dbContext);
}).As<IWechatService>().InstancePerLifetimeScope();
// 注册 IP 地理位置服务