fix: 微信openid绑定重复时不污染外层事务,登录可正常回落

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
XingQue
2026-07-09 01:18:42 +08:00
parent 5754f6a509
commit d64042fe46

View File

@@ -58,27 +58,33 @@ def find_user_by_wx_openid(club_id, openid):
from users.business_models import User
openid = (openid or '').strip()
club_id = (club_id or '').strip()
if not openid:
return None
def _user_by_uid(uid):
if not uid:
return None
user = User.objects.filter(UserUID=uid).first()
if not user:
user = User.query.filter(UserUID=uid).first()
return user
# 已有 openid 绑定(任意俱乐部)优先,避免重复注册
binding_any = UserWxOpenid.query.filter(openid=openid).order_by('id').first()
if binding_any:
user = _user_by_uid(binding_any.yonghuid)
if user:
return user
if club_id:
binding = UserWxOpenid.query.filter(club_id=club_id, openid=openid).first()
if binding:
user = User.objects.filter(UserUID=binding.yonghuid).first()
if not user:
user = User.query.filter(UserUID=binding.yonghuid).first()
user = _user_by_uid(binding.yonghuid)
if user:
return user
binding_any = UserWxOpenid.query.filter(openid=openid).order_by('id').first()
if binding_any:
user = User.objects.filter(UserUID=binding_any.yonghuid).first()
if not user:
user = User.query.filter(UserUID=binding_any.yonghuid).first()
if user:
return user
# 星之界等用户常 UserName=openid 且 OpenID 为空,优先按 UserName 查
# 星之界等用户常 UserName=openid 且 OpenID 为空
for manager in _user_querysets():
user = manager.filter(UserName=openid).first()
if user:
@@ -96,11 +102,16 @@ def ensure_wx_openid_binding(club_id, openid, user, unionid=''):
if not uid:
return None
club_id = (club_id or '').strip()
openid = (openid or '').strip()
binding = UserWxOpenid.query.filter(club_id=club_id, openid=openid).first()
if binding:
return binding
try:
# 独立 savepoint并发/重复绑定时不污染外层 transaction.atomic
with transaction.atomic():
return UserWxOpenid.query.create(
club_id=club_id,
openid=openid,
@@ -121,6 +132,7 @@ def resolve_or_create_wx_user(club_id, openid, generate_uid, unionid=''):
from users.business_models import User
openid = (openid or '').strip()
club_id = (club_id or '').strip()
if not openid:
raise ValueError('openid 不能为空')
@@ -130,7 +142,6 @@ def resolve_or_create_wx_user(club_id, openid, generate_uid, unionid=''):
return user, False
try:
# 嵌套 savepoint并发注册撞唯一键时只回滚创建不污染外层 atomic
with transaction.atomic():
user = User(
UserUUID=uuid.uuid4().bytes,
@@ -141,8 +152,6 @@ def resolve_or_create_wx_user(club_id, openid, generate_uid, unionid=''):
ClubID='',
)
user.save()
ensure_wx_openid_binding(club_id, openid, user, unionid)
return user, True
except IntegrityError:
user = find_user_by_wx_openid(club_id, openid)
if not user:
@@ -150,6 +159,9 @@ def resolve_or_create_wx_user(club_id, openid, generate_uid, unionid=''):
ensure_wx_openid_binding(club_id, openid, user, unionid)
return user, False
ensure_wx_openid_binding(club_id, openid, user, unionid)
return user, True
def get_user_club_id(user):
"""