diff --git a/jituan/services/wechat_login.py b/jituan/services/wechat_login.py index 8bf937a..0731f2d 100644 --- a/jituan/services/wechat_login.py +++ b/jituan/services/wechat_login.py @@ -4,7 +4,7 @@ import random import time import uuid -from django.db import transaction +from django.db import IntegrityError, transaction from django.utils import timezone from rest_framework_simplejwt.tokens import RefreshToken @@ -105,6 +105,37 @@ def _collect_role_status(user): } +def _find_user_by_openid_legacy(openid): + """兼容旧登录/扫码注册:User.OpenID 或 UserName 存的是 openid。""" + user = User.query.filter(OpenID=openid).first() + if not user: + user = User.objects.filter(OpenID=openid).first() + if not user: + user = User.query.filter(UserName=openid).first() + if not user: + user = User.objects.filter(UserName=openid).first() + return user + + +def _ensure_wx_binding(resolved_club_id, openid, user, unionid=''): + binding = UserWxOpenid.query.filter( + club_id=resolved_club_id, openid=openid, + ).first() + if binding: + return binding + try: + return UserWxOpenid.query.create( + club_id=resolved_club_id, + openid=openid, + yonghuid=user.UserUID, + unionid=unionid or user.UnionID or '', + ) + except IntegrityError: + return UserWxOpenid.query.filter( + club_id=resolved_club_id, openid=openid, + ).first() + + def login_or_register_by_club(code, club_id=None, app_id=None, client_ip=''): """ 俱乐部微信登录核心逻辑。 @@ -132,17 +163,10 @@ def login_or_register_by_club(code, club_id=None, app_id=None, client_ip=''): if not user: user = User.objects.filter(UserUID=binding.yonghuid).first() - if not user and resolved_club_id == CLUB_ID_DEFAULT: - user = User.query.filter(OpenID=openid).first() - if not user: - user = User.objects.filter(OpenID=openid).first() + if not user: + user = _find_user_by_openid_legacy(openid) if user: - UserWxOpenid.query.create( - club_id=resolved_club_id, - openid=openid, - yonghuid=user.UserUID, - unionid=unionid or user.UnionID, - ) + _ensure_wx_binding(resolved_club_id, openid, user, unionid) if not user: user_uuid = uuid.uuid4().bytes @@ -154,16 +178,18 @@ def login_or_register_by_club(code, club_id=None, app_id=None, client_ip=''): OpenID=openid if resolved_club_id == CLUB_ID_DEFAULT else None, UnionID=unionid or None, ) - user.save() - created = True - _ensure_boss_profile(user) - _ensure_consumer_role(user) - UserWxOpenid.query.create( - club_id=resolved_club_id, - openid=openid, - yonghuid=user.UserUID, - unionid=unionid, - ) + try: + user.save() + except IntegrityError: + user = _find_user_by_openid_legacy(openid) + if not user: + raise + _ensure_wx_binding(resolved_club_id, openid, user, unionid) + else: + created = True + _ensure_boss_profile(user) + _ensure_consumer_role(user) + _ensure_wx_binding(resolved_club_id, openid, user, unionid) if unionid and unionid != (user.UnionID or ''): user.UnionID = unionid