1
0
mirror of synced 2026-02-13 07:37:48 +08:00

添加直接获取配置的方法,改进多商户配置管理

Co-authored-by: binarywang <1343140+binarywang@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2026-01-19 03:54:42 +00:00
parent 8512374940
commit 742e757f1d
4 changed files with 271 additions and 6 deletions

View File

@@ -785,11 +785,33 @@ public interface WxPayService {
/**
* 获取配置.
* 在多商户配置场景下,会根据 WxPayConfigHolder 中的值获取对应的配置.
*
* @return the config
*/
WxPayConfig getConfig();
/**
* 根据商户号和 appId 直接获取配置.
* 此方法不依赖 ThreadLocal可以在任何上下文中使用适用于多商户管理场景.
*
* @param mchId 商户号
* @param appId 微信应用 id
* @return 对应的配置对象,如果不存在则返回 null
*/
WxPayConfig getConfig(String mchId, String appId);
/**
* 根据商户号直接获取配置.
* 此方法不依赖 ThreadLocal可以在任何上下文中使用.
* 适用于一个商户号对应多个 appId 的场景,会返回该商户号的任意一个配置.
* 注意:当存在多个匹配项时返回的配置是不可预测的,建议使用精确匹配方式.
*
* @param mchId 商户号
* @return 对应的配置对象,如果不存在则返回 null
*/
WxPayConfig getConfig(String mchId);
/**
* 设置配置对象.
*

View File

@@ -154,6 +154,45 @@ public abstract class BaseWxPayServiceImpl implements WxPayService {
return this.configMap.get(WxPayConfigHolder.get());
}
@Override
public WxPayConfig getConfig(String mchId, String appId) {
if (StringUtils.isBlank(mchId)) {
log.warn("商户号mchId不能为空");
return null;
}
if (StringUtils.isBlank(appId)) {
log.warn("应用ID appId不能为空");
return null;
}
String configKey = this.getConfigKey(mchId, appId);
return this.configMap.get(configKey);
}
@Override
public WxPayConfig getConfig(String mchId) {
if (StringUtils.isBlank(mchId)) {
log.warn("商户号mchId不能为空");
return null;
}
// 先尝试精确匹配针对只有mchId没有appId的配置
if (this.configMap.containsKey(mchId)) {
return this.configMap.get(mchId);
}
// 尝试前缀匹配(查找以 mchId_ 开头的配置)
String prefix = mchId + "_";
for (Map.Entry<String, WxPayConfig> entry : this.configMap.entrySet()) {
if (entry.getKey().startsWith(prefix)) {
log.debug("根据mchId=【{}】找到配置key=【{}】", mchId, entry.getKey());
return entry.getValue();
}
}
log.warn("无法找到对应mchId=【{}】的商户号配置信息", mchId);
return null;
}
@Override
public void setConfig(WxPayConfig config) {
final String defaultKey = this.getConfigKey(config.getMchId(), config.getAppId());

View File

@@ -52,6 +52,113 @@ public class MultiAppIdSwitchoverTest {
payService.setMultiConfig(configMap);
}
/**
* 测试直接通过 mchId 和 appId 获取配置(新功能)
*/
@Test
public void testGetConfigWithMchIdAndAppId() {
// 测试获取第一个配置
WxPayConfig config1 = payService.getConfig(testMchId, testAppId1);
assertNotNull(config1, "应该能够获取到配置");
assertEquals(config1.getMchId(), testMchId);
assertEquals(config1.getAppId(), testAppId1);
assertEquals(config1.getMchKey(), "test_key_1");
// 测试获取第二个配置
WxPayConfig config2 = payService.getConfig(testMchId, testAppId2);
assertNotNull(config2);
assertEquals(config2.getAppId(), testAppId2);
assertEquals(config2.getMchKey(), "test_key_2");
// 测试获取第三个配置
WxPayConfig config3 = payService.getConfig(testMchId, testAppId3);
assertNotNull(config3);
assertEquals(config3.getAppId(), testAppId3);
assertEquals(config3.getMchKey(), "test_key_3");
}
/**
* 测试直接通过 mchId 获取配置(新功能)
*/
@Test
public void testGetConfigWithMchIdOnly() {
WxPayConfig config = payService.getConfig(testMchId);
assertNotNull(config, "应该能够通过mchId获取配置");
assertEquals(config.getMchId(), testMchId);
// appId应该是三个中的一个
String currentAppId = config.getAppId();
assertTrue(
testAppId1.equals(currentAppId) || testAppId2.equals(currentAppId) || testAppId3.equals(currentAppId),
"获取的配置的appId应该是配置的appId之一"
);
}
/**
* 测试 getConfig 方法不依赖 ThreadLocal
* 在不切换配置的情况下也能直接获取
*/
@Test
public void testGetConfigWithoutSwitchover() {
// 不进行任何switchover操作直接通过参数获取配置
WxPayConfig config1 = payService.getConfig(testMchId, testAppId1);
WxPayConfig config2 = payService.getConfig(testMchId, testAppId2);
WxPayConfig config3 = payService.getConfig(testMchId, testAppId3);
// 验证可以同时获取到所有配置,不受 ThreadLocal 影响
assertNotNull(config1);
assertNotNull(config2);
assertNotNull(config3);
assertEquals(config1.getAppId(), testAppId1);
assertEquals(config2.getAppId(), testAppId2);
assertEquals(config3.getAppId(), testAppId3);
}
/**
* 测试 getConfig 方法处理不存在的配置
*/
@Test
public void testGetConfigWithNonexistentConfig() {
// 测试不存在的商户号和appId组合
WxPayConfig config = payService.getConfig("nonexistent_mch_id", "nonexistent_app_id");
assertNull(config, "获取不存在的配置应该返回null");
// 测试存在商户号但不存在的appId
config = payService.getConfig(testMchId, "wx9999999999999999");
assertNull(config, "获取不存在的appId配置应该返回null");
}
/**
* 测试 getConfig 方法处理空参数或null参数
*/
@Test
public void testGetConfigWithNullOrEmptyParameters() {
// 测试 null 商户号
WxPayConfig config = payService.getConfig(null, testAppId1);
assertNull(config, "商户号为null时应该返回null");
// 测试空商户号
config = payService.getConfig("", testAppId1);
assertNull(config, "商户号为空字符串时应该返回null");
// 测试 null appId
config = payService.getConfig(testMchId, null);
assertNull(config, "appId为null时应该返回null");
// 测试空 appId
config = payService.getConfig(testMchId, "");
assertNull(config, "appId为空字符串时应该返回null");
// 测试仅mchId方法的null参数
config = payService.getConfig((String) null);
assertNull(config, "商户号为null时应该返回null");
// 测试仅mchId方法的空字符串
config = payService.getConfig("");
assertNull(config, "商户号为空字符串时应该返回null");
}
/**
* 测试使用 mchId + appId 精确切换(原有功能,确保向后兼容)
*/