fix(auth): 微信 unionid 账号打通逻辑修复(老账号自动关联 + 查找顺序优化 + 冲突保护) #1738
Reference in New Issue
Block a user
Delete Branch "fix/wechat-unionid-account-linking"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
背景
小程序刚绑定到微信开放平台(企业主体)。绑定前小程序登录已创建过无 unionid 的老账号;绑定后这些老账号无法与 Web 扫码(同一微信用户、同 unionid)账号自动关联,导致同一人两端落到不同 user_id。
根因
WechatSyncUseCase.execute存在两个缺陷:wechat_unionid为空,即使本次请求带了 unionid 也不会回填,之后每次登录都只走 openid 分支,永远关联不上。修改点(packages/application/auth/wechat_sync_use_case.py)
测试
tests/unit/test_wechat_sync_use_case.py:20 个用例,覆盖 openid 登录、老账号补写 unionid、unionid 跨端绑定新 openid、三类冲突拒绝、新用户创建、用户名冲突、session 保存等。配套数据修复
staging 存量重复账号(应赐恩 Web 账号 30c14e1… 与小程序账号 5e20fdb7…)将通过数据修复脚本合并,与本 PR 独立。
⚠️ 仅部署 staging 验证,不动生产。
🚀 预览环境已部署
【阻塞级判定】
📊 审查概览
🔴 阻塞级问题(必须修复)
无
💡 改进建议(不阻塞合并)
elif openid_user分支中,再次调用self.user_repository.find_by_wechat_unionid(request.unionid)是冗余的。unionid_user = self.user_repository.find_by_wechat_unionid(request.unionid)(第117行)。只有当unionid_user为空时,才会进入elif openid_user分支。因此,在第145行再次查询 unionid 必然返回 None(除非在极短时间内发生了数据变更,但此时应依赖数据库唯一索引约束而非应用层查询)。if unionid_user and openid_user分支被拦截并报错。✅ 良好实践
TestWechatSyncConflicts),覆盖了核心业务逻辑,质量较高。✅ 格式检查通过 | ✅ 逻辑审查通过 | ✅ 性能无明显问题
🤖 由 AI 代码审查机器人自动生成 | 2026-09-06 06:39:46 | 模型:
🗑️ 预览环境已清理
PR #1738 已关闭或合并,对应的预览环境已被清理。