Compare commits
2 Commits
03c94624d0
...
e73e0fb6b5
| Author | SHA1 | Date | |
|---|---|---|---|
| e73e0fb6b5 | |||
| 3c89cbce40 |
17
.workbuddy/expert-history.json
Normal file
17
.workbuddy/expert-history.json
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"version": 2,
|
||||||
|
"sessions": {
|
||||||
|
"da2fb4dc76a94426a7dfef478f674489": [
|
||||||
|
{
|
||||||
|
"expertId": "SeniorDeveloper",
|
||||||
|
"name": "Will",
|
||||||
|
"profession": "高级开发工程师",
|
||||||
|
"avatarUrl": "https://acc-1258344699.cos.accelerate.myqcloud.com/workbuddy/experts/avatars/02-Engineering/SeniorDeveloper/SeniorDeveloper.png",
|
||||||
|
"promptUrl": "https://acc-1258344699.cos.accelerate.myqcloud.com/workbuddy/experts/experts/02-Engineering/SeniorDeveloper/SeniorDeveloper_zh.md",
|
||||||
|
"usedAt": 1775495439006,
|
||||||
|
"industryId": "all"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"lastUpdated": 1775497010453
|
||||||
|
}
|
||||||
12
.workbuddy/memory/2026-04-07.md
Normal file
12
.workbuddy/memory/2026-04-07.md
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
## 2026-04-07 工作记录
|
||||||
|
|
||||||
|
### 微信扫码登录问题修复
|
||||||
|
1. 修复了UserSyncService中tenant_id字段名问题(从tenantId改为tenant_id)
|
||||||
|
2. 同时发送两种格式的tenant_id字段确保兼容性
|
||||||
|
3. 修改了WxOfficialController,在同步前从数据库重新加载用户对象
|
||||||
|
4. 添加了详细的调试日志便于问题排查
|
||||||
|
|
||||||
|
### 待解决问题
|
||||||
|
1. websopy侧app_user_cache同步失败(tenant_id为null)
|
||||||
|
2. 扫码成功后需跳转到强制绑定手机号页面
|
||||||
|
3. 注册成功后应跳转到控制台/console
|
||||||
@@ -37,6 +37,15 @@ public class QrLoginStatusResponse {
|
|||||||
@Schema(description = "状态提示信息")
|
@Schema(description = "状态提示信息")
|
||||||
private String message;
|
private String message;
|
||||||
|
|
||||||
|
@Schema(description = "下一步操作:bind_phone-绑定手机号, redirect-跳转, login-直接登录")
|
||||||
|
private String nextAction;
|
||||||
|
|
||||||
|
@Schema(description = "跳转URL(当nextAction为redirect时使用)")
|
||||||
|
private String redirectUrl;
|
||||||
|
|
||||||
|
@Schema(description = "成功消息")
|
||||||
|
private String successMessage;
|
||||||
|
|
||||||
public QrLoginStatusResponse(String status, String accessToken, User userInfo, Long expiresIn, Integer tenantId) {
|
public QrLoginStatusResponse(String status, String accessToken, User userInfo, Long expiresIn, Integer tenantId) {
|
||||||
this.status = status;
|
this.status = status;
|
||||||
this.accessToken = accessToken;
|
this.accessToken = accessToken;
|
||||||
|
|||||||
@@ -442,6 +442,18 @@ public class QrLoginServiceImpl implements QrLoginService {
|
|||||||
|| QR_LOGIN_STATUS_BIND_PHONE.equals(qrLoginData.getStatus()));
|
|| QR_LOGIN_STATUS_BIND_PHONE.equals(qrLoginData.getStatus()));
|
||||||
response.setMessage(qrLoginData.getMessage());
|
response.setMessage(qrLoginData.getMessage());
|
||||||
|
|
||||||
|
// 设置下一步操作逻辑
|
||||||
|
if (QR_LOGIN_STATUS_BIND_PHONE.equals(qrLoginData.getStatus()) || Boolean.TRUE.equals(qrLoginData.getNeedBindPhone())) {
|
||||||
|
response.setNextAction("bind_phone");
|
||||||
|
response.setRedirectUrl(null);
|
||||||
|
} else if (QR_LOGIN_STATUS_CONFIRMED.equals(qrLoginData.getStatus()) && StrUtil.isNotBlank(qrLoginData.getAccessToken())) {
|
||||||
|
response.setNextAction("redirect");
|
||||||
|
response.setRedirectUrl("/console");
|
||||||
|
response.setSuccessMessage("登录成功,即将跳转到控制台");
|
||||||
|
} else {
|
||||||
|
response.setNextAction("wait");
|
||||||
|
}
|
||||||
|
|
||||||
if (qrLoginData.getUserId() != null) {
|
if (qrLoginData.getUserId() != null) {
|
||||||
try {
|
try {
|
||||||
User user = userService.getAllByUserId(String.valueOf(qrLoginData.getUserId()));
|
User user = userService.getAllByUserId(String.valueOf(qrLoginData.getUserId()));
|
||||||
|
|||||||
@@ -26,6 +26,22 @@ import java.util.Map;
|
|||||||
@Slf4j
|
@Slf4j
|
||||||
@Service
|
@Service
|
||||||
public class UserSyncService {
|
public class UserSyncService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转义JSON字符串中的特殊字符
|
||||||
|
*/
|
||||||
|
private String escapeJson(String str) {
|
||||||
|
if (str == null) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return str.replace("\\", "\\\\")
|
||||||
|
.replace("\"", "\\\"")
|
||||||
|
.replace("\b", "\\b")
|
||||||
|
.replace("\f", "\\f")
|
||||||
|
.replace("\n", "\\n")
|
||||||
|
.replace("\r", "\\r")
|
||||||
|
.replace("\t", "\\t");
|
||||||
|
}
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private ConfigProperties configProperties;
|
private ConfigProperties configProperties;
|
||||||
@@ -55,29 +71,32 @@ public class UserSyncService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// 构建请求体
|
// 构建请求体 - 使用手动JSON构建确保字段正确
|
||||||
JSONObject userCache = new JSONObject();
|
|
||||||
userCache.put("userId", user.getUserId());
|
|
||||||
userCache.put("username", user.getUsername());
|
|
||||||
userCache.put("nickname", user.getNickname());
|
|
||||||
userCache.put("avatar", user.getAvatar());
|
|
||||||
userCache.put("phone", user.getPhone());
|
|
||||||
userCache.put("status", user.getStatus());
|
|
||||||
userCache.put("updateTime", LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
|
|
||||||
// tenantId 可能为 null,但在 websopy 端是必填字段,至少传 0
|
|
||||||
// 注意:websopy 端数据库字段是 tenant_id(下划线),不是 tenantId(驼峰)
|
|
||||||
Integer tenantIdValue = user.getTenantId() != null ? user.getTenantId() : 0;
|
Integer tenantIdValue = user.getTenantId() != null ? user.getTenantId() : 0;
|
||||||
userCache.put("tenant_id", tenantIdValue);
|
|
||||||
|
// 构建JSON字符串,确保tenant_id字段存在且不为null
|
||||||
|
StringBuilder jsonBuilder = new StringBuilder();
|
||||||
|
jsonBuilder.append("{");
|
||||||
|
jsonBuilder.append("\"userId\":").append(user.getUserId()).append(",");
|
||||||
|
jsonBuilder.append("\"username\":\"").append(escapeJson(user.getUsername())).append("\",");
|
||||||
|
jsonBuilder.append("\"nickname\":\"").append(escapeJson(user.getNickname())).append("\",");
|
||||||
|
jsonBuilder.append("\"avatar\":\"").append(escapeJson(user.getAvatar())).append("\",");
|
||||||
|
jsonBuilder.append("\"phone\":\"").append(escapeJson(user.getPhone())).append("\",");
|
||||||
|
jsonBuilder.append("\"status\":").append(user.getStatus()).append(",");
|
||||||
|
jsonBuilder.append("\"updateTime\":\"").append(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))).append("\",");
|
||||||
|
jsonBuilder.append("\"tenantId\":").append(tenantIdValue).append(","); // 驼峰格式
|
||||||
|
jsonBuilder.append("\"tenant_id\":").append(tenantIdValue); // 下划线格式
|
||||||
|
jsonBuilder.append("}");
|
||||||
|
|
||||||
String url = websopyBaseUrl + "/api/app/user-sync/single";
|
String url = websopyBaseUrl + "/api/app/user-sync/single";
|
||||||
String body = userCache.toJSONString();
|
String body = jsonBuilder.toString();
|
||||||
|
|
||||||
log.info("同步用户到 websopy: userId={}, username={}, nickname={}, phone={}, tenantId={}, url={}",
|
log.info("同步用户到 websopy: userId={}, username={}, nickname={}, phone={}, tenantId={}, url={}",
|
||||||
user.getUserId(), user.getUsername(), user.getNickname(), user.getPhone(), user.getTenantId(), url);
|
user.getUserId(), user.getUsername(), user.getNickname(), user.getPhone(), user.getTenantId(), url);
|
||||||
log.debug("同步用户请求体: {}", body);
|
log.info("同步用户请求体JSON: {}", body); // 改为info级别以便查看
|
||||||
// 额外日志:tenantId 值检查
|
// 额外日志:tenantId 值检查
|
||||||
log.debug("tenantId检查 - 原始值: {}, 转换后值: {}, 请求体中tenant_id字段: {}",
|
log.debug("tenantId检查 - 原始值: {}, 转换后值: {}",
|
||||||
user.getTenantId(), tenantIdValue, userCache.get("tenant_id"));
|
user.getTenantId(), tenantIdValue);
|
||||||
|
|
||||||
// 发送 HTTP POST 请求
|
// 发送 HTTP POST 请求
|
||||||
Map<String, String> headers = new HashMap<>();
|
Map<String, String> headers = new HashMap<>();
|
||||||
|
|||||||
Reference in New Issue
Block a user