diff --git a/jituan/services/club_user.py b/jituan/services/club_user.py index 34db884..af6cd8f 100644 --- a/jituan/services/club_user.py +++ b/jituan/services/club_user.py @@ -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,17 +102,22 @@ 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: - return UserWxOpenid.query.create( - club_id=club_id, - openid=openid, - yonghuid=uid, - unionid=unionid or getattr(user, 'UnionID', None) or '', - ) + # 独立 savepoint:并发/重复绑定时不污染外层 transaction.atomic + with transaction.atomic(): + return UserWxOpenid.query.create( + club_id=club_id, + openid=openid, + yonghuid=uid, + unionid=unionid or getattr(user, 'UnionID', None) or '', + ) except IntegrityError: return UserWxOpenid.query.filter(club_id=club_id, openid=openid).first() @@ -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): """