feat(login): 实现扫码登录绑定手机号后的用户同步逻辑
- 后端QrLoginServiceImpl新增nextAction字段支持绑定手机号和跳转操作 - 状态检查接口支持绑定手机号和跳转状态,响应字段增加redirectUrl和successMessage - 移除新用户注册时立即同步用户到websopy的逻辑,避免手机号未绑定时缓存无效 - 绑定手机号成功后重新加载数据库用户并同步到websopy,确保手机号完整数据同步 - WxOfficialController中注释和逻辑调整,明确绑定手机号前不进行同步操作 - 补充文档中扫码登录绑定手机号和用户同步相关流程及API接口说明
This commit is contained in:
@@ -13,5 +13,5 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"lastUpdated": 1775497544505
|
"lastUpdated": 1775498241052
|
||||||
}
|
}
|
||||||
@@ -9,4 +9,33 @@
|
|||||||
### 待解决问题
|
### 待解决问题
|
||||||
1. websopy侧app_user_cache同步失败(tenant_id为null)
|
1. websopy侧app_user_cache同步失败(tenant_id为null)
|
||||||
2. 扫码成功后需跳转到强制绑定手机号页面
|
2. 扫码成功后需跳转到强制绑定手机号页面
|
||||||
3. 注册成功后应跳转到控制台/console
|
3. 注册成功后应跳转到控制台/console
|
||||||
|
|
||||||
|
### websopy-pc前端修改需求分析
|
||||||
|
1. **状态检查逻辑更新**:需处理新的nextAction字段(bind_phone, redirect, login等)
|
||||||
|
2. **新增绑定手机号页面**:用于新用户绑定手机号流程
|
||||||
|
3. **页面跳转逻辑**:登录成功/绑定成功后跳转到/console
|
||||||
|
4. **API调用更新**:适应新的响应字段格式
|
||||||
|
|
||||||
|
### 后端修改完成
|
||||||
|
1. **QrLoginStatusResponse新增字段**:
|
||||||
|
- nextAction: 下一步操作指示
|
||||||
|
- redirectUrl: 跳转URL(当nextAction为redirect时)
|
||||||
|
- successMessage: 成功消息
|
||||||
|
2. **QrLoginServiceImpl逻辑更新**:
|
||||||
|
- 用户没有手机号时,nextAction设为bind_phone
|
||||||
|
- 用户有手机号且登录成功时,nextAction设为redirect,redirectUrl设为/console
|
||||||
|
## 扫码登录用户同步时机修改 (01:58)
|
||||||
|
|
||||||
|
### 修改内容
|
||||||
|
1. **WxOfficialController.java** - 移除新用户注册时立即同步的代码
|
||||||
|
- processWxUser() 方法中,新用户创建后不再立即同步到 websopy
|
||||||
|
- findOrCreateUserForOauth() 方法中同样处理
|
||||||
|
|
||||||
|
2. **QrLoginServiceImpl.java** - 在绑定手机号成功后同步
|
||||||
|
- 新增 UserSyncService 注入
|
||||||
|
- 在 bindPhone() 方法中,绑定手机号成功后从数据库重新加载用户并同步
|
||||||
|
|
||||||
|
### 目的
|
||||||
|
确保用户数据同步到 websopy 时,手机号字段已有值,避免无效的缓存数据。
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
# 系统架构和工作流程记录
|
||||||
|
|
||||||
|
## websopy系统架构
|
||||||
|
1. **Java后端服务**:提供API接口,处理微信扫码登录、用户同步等
|
||||||
|
2. **websopy-pc网站**:前端用户界面,调用后端API
|
||||||
|
3. **微信生态集成**:
|
||||||
|
- 微信公众号扫码登录
|
||||||
|
- 用户信息同步到websopy系统
|
||||||
|
|
||||||
|
## 扫码登录绑定手机号流程
|
||||||
|
1. **后端已完成修改**:
|
||||||
|
- QrLoginServiceImpl添加nextAction逻辑
|
||||||
|
- QrLoginStatusResponse新增nextAction、redirectUrl、successMessage字段
|
||||||
|
- 用户没有手机号时设为bind_phone状态
|
||||||
|
- 用户有手机号时可直接跳转/console
|
||||||
|
|
||||||
|
2. **websopy-pc前端需要修改**:
|
||||||
|
- 状态轮询逻辑需要处理nextAction字段
|
||||||
|
- 需要创建绑定手机号页面
|
||||||
|
- 需要调用绑定手机号API
|
||||||
|
- 需要实现登录成功后跳转逻辑
|
||||||
|
|
||||||
|
## 关键API接口
|
||||||
|
- `/api/qr-login/generate` - 生成扫码token
|
||||||
|
- `/api/qr-login/status/{token}` - 检查扫码状态
|
||||||
|
- `/api/qr-login/bind-phone` - 绑定手机号
|
||||||
|
|
||||||
|
## 错误修复历史
|
||||||
|
- 修复了`Column 'tenant_id' cannot be null`错误
|
||||||
|
- 用户同步时确保同时发送tenantId和tenant_id两种格式
|
||||||
|
- 同步用户前从数据库重新加载确保数据完整
|
||||||
@@ -20,6 +20,7 @@ import com.gxwebsoft.common.system.entity.User;
|
|||||||
import com.gxwebsoft.common.system.entity.UserOauth;
|
import com.gxwebsoft.common.system.entity.UserOauth;
|
||||||
import com.gxwebsoft.common.system.service.UserOauthService;
|
import com.gxwebsoft.common.system.service.UserOauthService;
|
||||||
import com.gxwebsoft.common.system.service.UserService;
|
import com.gxwebsoft.common.system.service.UserService;
|
||||||
|
import com.gxwebsoft.common.system.service.UserSyncService;
|
||||||
import com.gxwebsoft.common.system.service.WxService;
|
import com.gxwebsoft.common.system.service.WxService;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
@@ -59,6 +60,9 @@ public class QrLoginServiceImpl implements QrLoginService {
|
|||||||
@Autowired(required = false)
|
@Autowired(required = false)
|
||||||
private UserOauthService userOauthService;
|
private UserOauthService userOauthService;
|
||||||
|
|
||||||
|
@Autowired(required = false)
|
||||||
|
private UserSyncService userSyncService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public QrLoginGenerateResponse generateQrLoginToken(Integer tenantId) {
|
public QrLoginGenerateResponse generateQrLoginToken(Integer tenantId) {
|
||||||
String token = UUID.randomUUID().toString(true);
|
String token = UUID.randomUUID().toString(true);
|
||||||
@@ -291,6 +295,15 @@ public class QrLoginServiceImpl implements QrLoginService {
|
|||||||
userService.updateUser(user);
|
userService.updateUser(user);
|
||||||
redisUtil.delete(codeKey);
|
redisUtil.delete(codeKey);
|
||||||
|
|
||||||
|
// 绑定手机号成功后,同步用户数据到 websopy
|
||||||
|
if (userSyncService != null) {
|
||||||
|
User updatedUser = userService.getAllByUserId(String.valueOf(user.getUserId()));
|
||||||
|
if (updatedUser != null) {
|
||||||
|
userSyncService.syncUserToWebsopy(updatedUser);
|
||||||
|
log.info("扫码绑定手机号后同步用户到websopy成功: userId={}, phone={}", user.getUserId(), user.getPhone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
String accessToken = buildAccessToken(user);
|
String accessToken = buildAccessToken(user);
|
||||||
qrLoginData.setStatus(QR_LOGIN_STATUS_CONFIRMED);
|
qrLoginData.setStatus(QR_LOGIN_STATUS_CONFIRMED);
|
||||||
qrLoginData.setUserId(user.getUserId());
|
qrLoginData.setUserId(user.getUserId());
|
||||||
|
|||||||
@@ -274,14 +274,7 @@ public class WxOfficialController extends BaseController {
|
|||||||
userRole.setTenantId(user.getTenantId());
|
userRole.setTenantId(user.getTenantId());
|
||||||
userRole.setRoleId(user.getRoleId());
|
userRole.setRoleId(user.getRoleId());
|
||||||
userRoleService.save(userRole);
|
userRoleService.save(userRole);
|
||||||
// 同步到 websopy - 从数据库重新加载确保有完整数据
|
// 注意:不立即同步到 websopy,等绑定手机号后再同步
|
||||||
User savedUser = userService.getAllByUserId(String.valueOf(userId));
|
|
||||||
if (savedUser != null) {
|
|
||||||
userSyncService.syncUserToWebsopy(savedUser);
|
|
||||||
} else {
|
|
||||||
// 如果无法重新加载,使用当前对象
|
|
||||||
userSyncService.syncUserToWebsopy(user);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
System.out.println("新微信公众号用户 userId = " + userId);
|
System.out.println("新微信公众号用户 userId = " + userId);
|
||||||
}
|
}
|
||||||
@@ -696,14 +689,7 @@ public class WxOfficialController extends BaseController {
|
|||||||
userRole.setTenantId(user.getTenantId());
|
userRole.setTenantId(user.getTenantId());
|
||||||
userRole.setRoleId(user.getRoleId());
|
userRole.setRoleId(user.getRoleId());
|
||||||
userRoleService.save(userRole);
|
userRoleService.save(userRole);
|
||||||
// 同步到 websopy - 从数据库重新加载确保有完整数据
|
// 注意:不立即同步到 websopy,等绑定手机号后再同步
|
||||||
User savedUser = userService.getAllByUserId(String.valueOf(userId));
|
|
||||||
if (savedUser != null) {
|
|
||||||
userSyncService.syncUserToWebsopy(savedUser);
|
|
||||||
} else {
|
|
||||||
// 如果无法重新加载,使用当前对象
|
|
||||||
userSyncService.syncUserToWebsopy(user);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
System.out.println("数据不一致:创建新用户 userId = " + userId);
|
System.out.println("数据不一致:创建新用户 userId = " + userId);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user