# 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`,而 `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` - 原因 1:app_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"),且表名必须带正确库名前缀**