From 11ee8d963ca24abbe4226d06b72704d04da1b27f Mon Sep 17 00:00:00 2001 From: zpc Date: Tue, 27 Jan 2026 13:18:10 +0800 Subject: [PATCH] 231 --- server/HoneyBox/src/HoneyBox.Api/Program.cs | 5 - .../src/HoneyBox.Api/appsettings.json | 4 - .../HoneyBox.Core/Services/WechatService.cs | 263 ++++++++---------- .../Modules/ServiceModule.cs | 3 +- 4 files changed, 118 insertions(+), 157 deletions(-) diff --git a/server/HoneyBox/src/HoneyBox.Api/Program.cs b/server/HoneyBox/src/HoneyBox.Api/Program.cs index ed10e664..1e182d8e 100644 --- a/server/HoneyBox/src/HoneyBox.Api/Program.cs +++ b/server/HoneyBox/src/HoneyBox.Api/Program.cs @@ -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); diff --git a/server/HoneyBox/src/HoneyBox.Api/appsettings.json b/server/HoneyBox/src/HoneyBox.Api/appsettings.json index 8460e4ee..ea3cd213 100644 --- a/server/HoneyBox/src/HoneyBox.Api/appsettings.json +++ b/server/HoneyBox/src/HoneyBox.Api/appsettings.json @@ -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": "默认商户", diff --git a/server/HoneyBox/src/HoneyBox.Core/Services/WechatService.cs b/server/HoneyBox/src/HoneyBox.Core/Services/WechatService.cs index 7a03b135..f5c2f605 100644 --- a/server/HoneyBox/src/HoneyBox.Core/Services/WechatService.cs +++ b/server/HoneyBox/src/HoneyBox.Core/Services/WechatService.cs @@ -17,7 +17,6 @@ public class WechatService : IWechatService { private readonly HttpClient _httpClient; private readonly ILogger _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 logger, - WechatSettings wechatSettings, IOptions 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 /// /// 获取小程序接口调用凭证(access_token) /// - /// 小程序AppId(可选,不传则使用默认配置) + /// 小程序AppId(可选,不传则使用数据库默认配置) /// access_token,失败返回null public async Task 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 } /// - /// 根据AppId获取对应的AppSecret + /// 根据AppId获取对应的AppSecret(异步版本,从数据库读取) /// - private string GetAppSecretByAppId(string appId) + private async Task 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; } /// @@ -598,85 +614,66 @@ public class WechatService : IWechatService /// /// 从数据库获取微信小程序配置 - /// 优先从 miniprogram_setting 读取默认小程序配置,如果没有则回退到 wechat_setting + /// 仅从 miniprogram_setting 读取,无配置则返回 null /// private async Task 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(miniprogramConfig); + _logger.LogWarning("[微信配置] 数据库中未找到 miniprogram_setting 配置"); + return null; + } + + var config = JsonSerializer.Deserialize(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(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; } /// - /// 获取商户配置(优先从数据库读取) + /// 获取商户配置(从数据库读取) /// private async Task 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(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(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(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(); - } - - /// - /// 获取商户配置(同步版本,用于兼容) - /// - private WechatPayMerchantConfig? GetMerchantConfig() - { - // 优先使用 appsettings.json 中的默认商户配置 - if (!string.IsNullOrEmpty(_wechatPaySettings.DefaultMerchant?.MchId)) - { - return _wechatPaySettings.DefaultMerchant; - } - - // 从商户列表中获取第一个 - return _wechatPaySettings.Merchants.FirstOrDefault(); } /// diff --git a/server/HoneyBox/src/HoneyBox.Infrastructure/Modules/ServiceModule.cs b/server/HoneyBox/src/HoneyBox.Infrastructure/Modules/ServiceModule.cs index f1718a0d..be5be189 100644 --- a/server/HoneyBox/src/HoneyBox.Infrastructure/Modules/ServiceModule.cs +++ b/server/HoneyBox/src/HoneyBox.Infrastructure/Modules/ServiceModule.cs @@ -26,11 +26,10 @@ public class ServiceModule : Module { var httpClientFactory = c.Resolve(); var logger = c.Resolve>(); - var wechatSettings = c.Resolve(); var wechatPaySettings = c.Resolve>(); var redisService = c.Resolve(); var dbContext = c.Resolve(); - return new WechatService(httpClientFactory.CreateClient(), logger, wechatSettings, wechatPaySettings, redisService, dbContext); + return new WechatService(httpClientFactory.CreateClient(), logger, wechatPaySettings, redisService, dbContext); }).As().InstancePerLifetimeScope(); // 注册 IP 地理位置服务