Compare commits

..

5 Commits

Author SHA1 Message Date
03cefc9048 Merge remote-tracking branch 'origin/master' 2026-06-21 10:32:58 +08:00
f5f9e3a19d fix(system): 调整小程序配置读取顺序
- 修改 getMpWxSetting 方法,优先读取 sys_setting(mp-weixin)
- 读取失败时回退到 db_websopy.app_config(category=wechat)
- 更新异常日志内容,明确读取失败顺序
- 适配业务需求调整配置优先级
- 影响所有调用 getMpWxSetting 的相关方法调用流程
2026-06-21 10:32:39 +08:00
7f341c2399 Merge remote-tracking branch 'origin/master' 2026-06-20 22:03:11 +08:00
2982818a0c 10198添加手机添加下级逻辑 2026-06-20 22:03:07 +08:00
307c209565 fix(appconfig): 修复跨表查询以确保产品有效性
- selectByCategory SQL 增加 INNER JOIN app_product,确保只返回该租户下有效产品配置
- 加入关联条件 ap.product_id = ac.app_id 和 ap.tenant_id = #{tenantId}
- 保证查询结果中 app_config 的 app_id 必须对应有效且属于当前租户的产品
- 维护原有租户过滤和配置类型过滤逻辑,增强数据准确性
- 该改动对 Service 和 Controller 层无影响,无需修改调用逻辑
2026-06-18 17:17:45 +08:00
4 changed files with 90 additions and 22 deletions

View File

@@ -0,0 +1,11 @@
# 2026-06-18 工作日志
## AppConfigMapper.xml 添加关联查询
**改动文件**: `src/main/java/com/gxwebsoft/websopy/mapper/AppConfigMapper.xml`
- `selectByCategory` SQL 增加了 `INNER JOIN db_websopy.app_product`,关联条件:
- `ap.product_id = ac.app_id`
- `ap.tenant_id = #{tenantId}`
- 目的:确保只返回该租户下有效产品的配置,防止 app_config 中的 app_id 指向非该租户的产品
- Service 层和 Controller 层无需改动,不影响现有调用

View File

@@ -0,0 +1,27 @@
# 2026-06-21 工作日志
## WxLoginController 配置读取顺序调整
### 修改内容
修改了 `WxLoginController.java` 中的 `getMpWxSetting` 方法,调整小程序配置读取顺序:
**修改前:**
- 优先:`db_websopy.app_config`category=wechat
- 兜底:`sys_setting.mp-weixin`
**修改后:**
- 优先:`sys_setting.mp-weixin`
- 兜底:`db_websopy.app_config`category=wechat
### 修改原因
业务需求变更需要优先从系统设置sys_setting读取小程序配置数据库配置app_config作为兜底方案。
### 影响范围
影响所有调用 `getMpWxSetting` 方法的地方:
- `getOpenIdByCode` - 获取 openid
- `getAccessToken` - 获取 access_token
- `loginByOpenId` - openid 无感登录
- `getWxOpenId` / `getWxOpenIdOnly` - 获取微信 openId
### 文件位置
`/Users/gxwebsoft/JAVA/com.gxwebsoft.core/src/main/java/com/gxwebsoft/common/system/controller/WxLoginController.java`

View File

@@ -199,6 +199,7 @@ public class WxLoginController extends BaseController {
String access_token = JwtUtil.buildToken(new JwtSubject(user.getUsername(), user.getTenantId()),
configProperties.getTokenExpireTime(), configProperties.getTokenKey());
loginRecordService.saveAsync(user.getUsername(), LoginRecord.TYPE_LOGIN, null, user.getTenantId(), request);
if (getTenantId() != null && getTenantId().equals(10198)) activateShopUserMemberByPhone(phone);
return success("登录成功", new LoginResult(access_token, user));
}
@@ -255,7 +256,7 @@ public class WxLoginController extends BaseController {
String access_token = JwtUtil.buildToken(new JwtSubject(user.getUsername(), user.getTenantId()),
configProperties.getTokenExpireTime(), configProperties.getTokenKey());
loginRecordService.saveAsync(user.getUsername(), LoginRecord.TYPE_REGISTER, null, user.getTenantId(), request);
if (getTenantId() != null && getTenantId().equals(10198)) activateShopUserMemberByPhone(phone);
return success("注册并登录成功", new LoginResult(access_token, user));
} catch (BusinessException e) {
@@ -267,6 +268,7 @@ public class WxLoginController extends BaseController {
String access_token = JwtUtil.buildToken(new JwtSubject(user.getUsername(), user.getTenantId()),
configProperties.getTokenExpireTime(), configProperties.getTokenKey());
loginRecordService.saveAsync(user.getUsername(), LoginRecord.TYPE_LOGIN, null, user.getTenantId(), request);
activateShopUserMemberByPhone(phone);
return success("登录成功", new LoginResult(access_token, user));
}
}
@@ -328,6 +330,7 @@ public class WxLoginController extends BaseController {
String access_token = JwtUtil.buildToken(new JwtSubject(user.getUsername(), user.getTenantId()),
configProperties.getTokenExpireTime(), configProperties.getTokenKey());
loginRecordService.saveAsync(user.getUsername(), LoginRecord.TYPE_LOGIN, null, user.getTenantId(), request);
activateShopUserMemberByPhone(phone);
return success("登录成功", new LoginResult(access_token, user));
}
@@ -401,6 +404,7 @@ public class WxLoginController extends BaseController {
String access_token = JwtUtil.buildToken(new JwtSubject(user.getUsername(), user.getTenantId()),
configProperties.getTokenExpireTime(), configProperties.getTokenKey());
loginRecordService.saveAsync(user.getUsername(), LoginRecord.TYPE_REGISTER, null, user.getTenantId(), request);
activateShopUserMemberByPhone(phone);
return success("注册并登录成功", new LoginResult(access_token, user));
@@ -413,6 +417,7 @@ public class WxLoginController extends BaseController {
String access_token = JwtUtil.buildToken(new JwtSubject(user.getUsername(), user.getTenantId()),
configProperties.getTokenExpireTime(), configProperties.getTokenKey());
loginRecordService.saveAsync(user.getUsername(), LoginRecord.TYPE_LOGIN, null, user.getTenantId(), request);
activateShopUserMemberByPhone(phone);
return success("登录成功", new LoginResult(access_token, user));
}
}
@@ -420,6 +425,26 @@ public class WxLoginController extends BaseController {
}
}
private void activateShopUserMemberByPhone(String phone) {
if (StrUtil.isBlank(phone)) {
return;
}
try {
String apiUrl = "https://paopao-api.websoft.top/api/shop/shop-user-member/activate-by-phone";
String normalizedPhone = phone.trim();
JSONObject body = new JSONObject();
body.put("phone", normalizedPhone);
String response = HttpRequest.post(apiUrl)
.header("Content-Type", "application/json")
.body(body.toJSONString())
.execute()
.body();
System.out.println("激活会员记录响应: " + response);
} catch (Exception e) {
System.err.println("激活会员记录失败,但不影响登录流程: " + e.getMessage());
}
}
@Operation(summary = "微信授权手机号码并更新")
@Transactional(rollbackFor = {Exception.class})
@PostMapping("/updatePhoneByMpWx")
@@ -437,7 +462,7 @@ public class WxLoginController extends BaseController {
}
/**
* 优先读取 db_websopy.app_configcategory=wechat,不存在或异常时回退到 sys_setting (mp-weixin)
* 优先读取 sys_setting (mp-weixin),不存在或异常时回退到 db_websopy.app_configcategory=wechat
*
* @param tenantId 租户ID传 null 时使用当前请求租户)
* @return JSONObject 配置内容(含 appId / appSecret 等字段)
@@ -445,15 +470,16 @@ public class WxLoginController extends BaseController {
private JSONObject getMpWxSetting(Integer tenantId) {
Integer tid = tenantId != null ? tenantId : getTenantId();
try {
JSONObject wechat = appConfigService.getByCategory("wechat", tid);
if (wechat != null && !wechat.isEmpty()) {
return wechat;
// 优先sys_setting.mp-weixin
JSONObject setting = settingService.getBySettingKey("mp-weixin");
if (setting != null && !setting.isEmpty()) {
return setting;
}
} catch (Exception e) {
System.err.println("[WxLoginController] 读取 app_config 失败,回退 sys_setting: " + e.getMessage());
System.err.println("[WxLoginController] 读取 sys_setting 失败,回退 app_config: " + e.getMessage());
}
// 兜底:原 sys_setting.mp-weixin
return settingService.getBySettingKey("mp-weixin");
// 兜底:db_websopy.app_configcategory=wechat
return appConfigService.getByCategory("wechat", tid);
}
/**

View File

@@ -3,27 +3,31 @@
<mapper namespace="com.gxwebsoft.websopy.mapper.AppConfigMapper">
<!--
跨表查询 db_websopy.app_config
跨表查询 db_websopy.app_config,关联 app_product 校验产品有效性
注意:
1. 表名带库名前缀 db_websopy.app_config该表在 db_websopy 库中)
2. Mapper 方法已加 @InterceptorIgnore(tenantLine = "true")
TenantLineInnerInterceptor 不会自动追加 tenant_id 条件
3. 手动传入 tenantId 参数精确匹配 app_config 自身的租户
4. INNER JOIN app_product确保只返回该租户下有效产品app_product.product_id = app_config.app_id的配置
-->
<select id="selectByCategory" resultType="com.gxwebsoft.websopy.entity.AppConfig">
SELECT config_id AS configId,
app_id AS appId,
tenant_id AS tenantId,
config_key AS configKey,
config_value AS configValue,
config_type AS configType,
is_encrypted AS isEncrypted,
is_secret AS isSecret,
description
FROM db_websopy.app_config
WHERE deleted = 0
AND tenant_id = #{tenantId}
AND config_type = #{configType}
SELECT ac.config_id AS configId,
ac.app_id AS appId,
ac.tenant_id AS tenantId,
ac.config_key AS configKey,
ac.config_value AS configValue,
ac.config_type AS configType,
ac.is_encrypted AS isEncrypted,
ac.is_secret AS isSecret,
ac.description
FROM db_websopy.app_config ac
INNER JOIN db_websopy.app_product ap
ON ap.product_id = ac.app_id
AND ap.tenant_id = #{tenantId}
WHERE ac.deleted = 0
AND ac.tenant_id = #{tenantId}
AND ac.config_type = #{configType}
</select>
</mapper>