refactor(wxlogin): 改造微信配置读取优先从 app_config 获取

- 新增 AppConfig 实体及跨库 Mapper、XML 实现 db_websopy.app_config 查询
- 增加 AppConfigService 提供带缓存的配置读取接口,缓存两小时
- WxLoginController 注入 AppConfigService,新增私有方法 getMpWxSetting()
- getMpWxSetting() 优先读取 app_config(category=wechat),失败回退 sys_setting.mp-weixin
- 替换微信小程序配置获取调用点,统一通过 getMpWxSetting() 获取配置
- 避免跨库 TenantLineInterceptor 干扰,Mapper 方法加 @InterceptorIgnore 标注
- 修正 StringRedisTemplate 注入避免 Bean 名冲突
- 新增读取失败或无配置时的降级和异常处理逻辑
- 日志补充便于排查配置读取过程及缓存情况
This commit is contained in:
2026-06-18 16:31:04 +08:00
parent 779f90e813
commit 797a140f11
6 changed files with 329 additions and 14 deletions

View File

@@ -0,0 +1,58 @@
# 2026-06-17
## WxLoginController 配置读取改造app_config 跨表查询)
### 需求
- `WxLoginController.loginByMpWxPhone` 等微信小程序相关接口读取配置时,优先从 `gxwebsoft_core.app_config`db_websopy 库)读取,命中失败时回退到 `gxwebsoft_core.sys_setting.mp-weixin`
- app_config 是 KV 行式存储:`id, tenant_id, config_key, config_value, category`(如 `category=wechat``config_key=wechat.appId`)。
### 方案(无需新建数据源)
- 直接 MyBatis XML 跨表:`FROM gxwebsoft_core.app_config`
- 走主数据源,依赖 gxwebsoft_core 库账号对 app_config 有 SELECT 权限
### 新增文件
- `src/main/java/com/gxwebsoft/websopy/entity/AppConfig.java` —— 实体
- `src/main/java/com/gxwebsoft/websopy/mapper/AppConfigMapper.java` —— Mapper声明 selectByCategory
- `src/main/java/com/gxwebsoft/websopy/mapper/AppConfigMapper.xml` —— XML 跨表查询(**XML 与 Mapper 同包**
- `src/main/java/com/gxwebsoft/websopy/service/AppConfigService.java` —— 带 Redis 缓存
### 改造 WxLoginController
- 注入 `AppConfigService appConfigService`
- 新增私有方法 `getMpWxSetting(Integer tenantId)`:先读 app_config category=wechat失败回退 `settingService.getBySettingKey("mp-weixin")`
- 替换 5 处调用:
- `getOpenIdByCode`(约 521 行)
- `getAccessToken(Integer)`(约 716 行)
- `getWxOpenId`(约 834 行)
- `getWxOpenIdOnly`(约 861 行)
- `loginByOpenId`(约 959 行,写回 AppId/AppSecret Redis 缓存保持一致)
### 关键细节
- 缓存 Key 前缀 `appConfig:{tenantId}:{category}`(与 setting:* 隔离)
- 缓存 TTL 2 小时
- 配置文件组装:去掉 `config_key` 中的 `wechat.` 前缀,直接得到 `appId`/`appSecret`
- 编译错误原因及修复Mapper interface 必须显式声明 selectByCategory 方法(编译期不查 XML
### 编译验证
- `./mvnw clean compile -DskipTests` 通过 ✅
### 运行期 BeanCreationException 修复2026-06-18 补记)
- 报错:`Bean named 'redisTemplate' expected StringRedisTemplate but was actually RedisTemplate`
- 原因:`@Resource` 按字段名bean name注入容器中 `redisTemplate``RedisTemplate<Object,Object>`,而 `StringRedisTemplate` bean 叫 `stringRedisTemplate`
- 修复:`AppConfigService` 字段名从 `redisTemplate` 改为 `stringRedisTemplate`4 处引用同步修改
- **项目规律:统一用字段名 `stringRedisTemplate`,禁止用 `redisTemplate` 注入 StringRedisTemplate**
### 运行期 SQLSyntaxErrorException 修复2026-06-18 补记)
- 报错:`Table 'gxwebsoft_core.app_config' doesn't exist` + TenantLineInnerInterceptor 自动追加 `AND tenant_id = 10611`
- 原因 1app_config 表实际在 `db_websopy` 库中,不在 gxwebsoft_core
- 原因 2`TenantLineInnerInterceptor` 对所有 SQL 自动追加 tenant_id 条件,导致参数重复
- 实际表结构(从用户截图确认):
- 主键 `config_id`(不是 id
- 分类字段 `config_type`(不是 category
-`deleted` 逻辑删除字段
- tenant_id 示例值 105885
- 修复:
1. XML 表名改为 `db_websopy.app_config`
2. Mapper 方法加 `@InterceptorIgnore(tenantLine = "true")`(与项目其他跨库 Mapper 一致)
3. 实体类字段对齐实际表结构configId/configType/deleted
4. Service 参数名 category → configType 全部对齐
- **关键教训:跨库查询必须加 @InterceptorIgnore(tenantLine="true"),且表名必须带正确库名前缀**