fix: 统一微信用户定位,修复wechatlogin等UserName(openid)重复1062
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -86,6 +86,40 @@ def ensure_wx_openid_binding(club_id, openid, user, unionid=''):
|
|||||||
return UserWxOpenid.query.filter(club_id=club_id, openid=openid).first()
|
return UserWxOpenid.query.filter(club_id=club_id, openid=openid).first()
|
||||||
|
|
||||||
|
|
||||||
|
def resolve_or_create_wx_user(club_id, openid, generate_uid, unionid=''):
|
||||||
|
"""
|
||||||
|
微信登录/注册统一找用户,避免 UserName(openid) 唯一键冲突。
|
||||||
|
星之界等俱乐部用户常 UserName=openid 且 OpenID 为空,不可 get_or_create(OpenID=...)。
|
||||||
|
返回 (user, created)。
|
||||||
|
"""
|
||||||
|
import uuid
|
||||||
|
from users.business_models import User
|
||||||
|
|
||||||
|
user = find_user_by_wx_openid(club_id, openid)
|
||||||
|
if user:
|
||||||
|
ensure_wx_openid_binding(club_id, openid, user, unionid)
|
||||||
|
return user, False
|
||||||
|
|
||||||
|
try:
|
||||||
|
user = User(
|
||||||
|
UserUUID=uuid.uuid4().bytes,
|
||||||
|
UserUID=generate_uid(),
|
||||||
|
UserName=openid,
|
||||||
|
OpenID=openid if club_id == CLUB_ID_DEFAULT else None,
|
||||||
|
UnionID=unionid or None,
|
||||||
|
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:
|
||||||
|
raise
|
||||||
|
ensure_wx_openid_binding(club_id, openid, user, unionid)
|
||||||
|
return user, False
|
||||||
|
|
||||||
|
|
||||||
def get_user_club_id(user):
|
def get_user_club_id(user):
|
||||||
"""
|
"""
|
||||||
解析用户归属 club(注册/邀请链隔离用)。
|
解析用户归属 club(注册/邀请链隔离用)。
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ from jituan.services.club_user import (
|
|||||||
ensure_user_club_id,
|
ensure_user_club_id,
|
||||||
ensure_wx_openid_binding,
|
ensure_wx_openid_binding,
|
||||||
find_user_by_wx_openid,
|
find_user_by_wx_openid,
|
||||||
|
resolve_or_create_wx_user,
|
||||||
)
|
)
|
||||||
from users.business_models import User
|
from users.business_models import User
|
||||||
from users.models import UserBoss, UserDashou, UserGuanshi, UserShangjia, UserZuzhang, UserShenheguan
|
from users.models import UserBoss, UserDashou, UserGuanshi, UserShangjia, UserZuzhang, UserShenheguan
|
||||||
@@ -138,34 +139,14 @@ def login_or_register_by_club(code, club_id=None, app_id=None, client_ip=''):
|
|||||||
user = User.objects.filter(UserUID=binding.yonghuid).first()
|
user = User.objects.filter(UserUID=binding.yonghuid).first()
|
||||||
|
|
||||||
if not user:
|
if not user:
|
||||||
user = find_user_by_wx_openid(resolved_club_id, openid)
|
user, created = resolve_or_create_wx_user(
|
||||||
if user:
|
resolved_club_id, openid, _generate_user_uid, unionid=unionid,
|
||||||
ensure_wx_openid_binding(resolved_club_id, openid, user, unionid)
|
|
||||||
|
|
||||||
if not user:
|
|
||||||
user_uuid = uuid.uuid4().bytes
|
|
||||||
new_uid = _generate_user_uid()
|
|
||||||
user = User(
|
|
||||||
UserUUID=user_uuid,
|
|
||||||
UserUID=new_uid,
|
|
||||||
UserName=openid,
|
|
||||||
OpenID=openid if resolved_club_id == CLUB_ID_DEFAULT else None,
|
|
||||||
UnionID=unionid or None,
|
|
||||||
ClubID='',
|
|
||||||
)
|
)
|
||||||
try:
|
if created:
|
||||||
from django.db import IntegrityError
|
|
||||||
user.save()
|
|
||||||
except IntegrityError:
|
|
||||||
user = find_user_by_wx_openid(resolved_club_id, openid)
|
|
||||||
if not user:
|
|
||||||
raise
|
|
||||||
ensure_wx_openid_binding(resolved_club_id, openid, user, unionid)
|
|
||||||
else:
|
|
||||||
created = True
|
|
||||||
_ensure_boss_profile(user)
|
_ensure_boss_profile(user)
|
||||||
_ensure_consumer_role(user)
|
_ensure_consumer_role(user)
|
||||||
ensure_wx_openid_binding(resolved_club_id, openid, user, unionid)
|
else:
|
||||||
|
ensure_wx_openid_binding(resolved_club_id, openid, user, unionid)
|
||||||
|
|
||||||
if unionid and unionid != (user.UnionID or ''):
|
if unionid and unionid != (user.UnionID or ''):
|
||||||
user.UnionID = unionid
|
user.UnionID = unionid
|
||||||
|
|||||||
@@ -123,20 +123,21 @@ class WechatMiniProgramLoginView(APIView):
|
|||||||
|
|
||||||
openid = wechat_data['openid']
|
openid = wechat_data['openid']
|
||||||
session_key = wechat_data.get('session_key', '')
|
session_key = wechat_data.get('session_key', '')
|
||||||
unionid = wechat_data.get('unionid', '') # 🆕【新增】获取unionid
|
unionid = wechat_data.get('unionid', '')
|
||||||
|
|
||||||
# 获取客户端真实IP
|
from jituan.services.club_resolver import resolve_club_id_for_wechat_request
|
||||||
|
from jituan.services.club_user import ensure_user_club_id, resolve_or_create_wx_user
|
||||||
|
|
||||||
|
club_id = resolve_club_id_for_wechat_request(request)
|
||||||
kehuduan_ip = self.huoquKehuduanIP(request)
|
kehuduan_ip = self.huoquKehuduanIP(request)
|
||||||
|
|
||||||
with transaction.atomic():
|
with transaction.atomic():
|
||||||
# 创建或获取用户
|
user_main, created = resolve_or_create_wx_user(
|
||||||
user_main, created = User.objects.select_for_update().get_or_create(
|
club_id, openid, self.shengchengYonghuID, unionid=unionid,
|
||||||
OpenID=openid,
|
|
||||||
defaults={'UserUID': self.shengchengYonghuID(), 'UserName': openid}
|
|
||||||
)
|
)
|
||||||
|
ensure_user_club_id(user_main, club_id)
|
||||||
|
|
||||||
# 保存unionid
|
if unionid and unionid != (user_main.UnionID or ''):
|
||||||
if unionid and unionid != user_main.UnionID:
|
|
||||||
user_main.UnionID = unionid
|
user_main.UnionID = unionid
|
||||||
|
|
||||||
user_main.IP = kehuduan_ip
|
user_main.IP = kehuduan_ip
|
||||||
@@ -842,35 +843,16 @@ class WechatLoginAndDashouRegisterView(APIView):
|
|||||||
from jituan.constants import CLUB_ID_DEFAULT
|
from jituan.constants import CLUB_ID_DEFAULT
|
||||||
from jituan.services.club_user import (
|
from jituan.services.club_user import (
|
||||||
ensure_user_club_id,
|
ensure_user_club_id,
|
||||||
ensure_wx_openid_binding,
|
resolve_or_create_wx_user,
|
||||||
find_user_by_wx_openid,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# 4. 开始数据库事务(确保登录和注册的原子性)
|
# 4. 开始数据库事务(确保登录和注册的原子性)
|
||||||
with transaction.atomic():
|
with transaction.atomic():
|
||||||
# 4.1 定位或创建用户(兼容俱乐部登录建立的 user_wx_openid)
|
user_main, created = resolve_or_create_wx_user(
|
||||||
user_main = find_user_by_wx_openid(club_id, openid)
|
club_id, openid, self.shengchengYonghuID, unionid=unionid,
|
||||||
created = False
|
)
|
||||||
|
if created:
|
||||||
if not user_main:
|
UserBoss.query.create(user=user_main, nickname='微信用户')
|
||||||
try:
|
|
||||||
user_main = User(
|
|
||||||
UserUUID=uuid.uuid4().bytes,
|
|
||||||
UserUID=self.shengchengYonghuID(),
|
|
||||||
UserName=openid,
|
|
||||||
OpenID=openid if club_id == CLUB_ID_DEFAULT else None,
|
|
||||||
UnionID=unionid or None,
|
|
||||||
ClubID='', # 勿用模型历史默认 xq,注册成功后再写
|
|
||||||
)
|
|
||||||
user_main.save()
|
|
||||||
created = True
|
|
||||||
UserBoss.query.create(user=user_main, nickname='微信用户')
|
|
||||||
except IntegrityError:
|
|
||||||
user_main = find_user_by_wx_openid(club_id, openid)
|
|
||||||
if not user_main:
|
|
||||||
raise
|
|
||||||
|
|
||||||
ensure_wx_openid_binding(club_id, openid, user_main, unionid)
|
|
||||||
|
|
||||||
# 更新用户IP和最后登录时间
|
# 更新用户IP和最后登录时间
|
||||||
cunchu_ip = kehuduan_ip
|
cunchu_ip = kehuduan_ip
|
||||||
@@ -1282,14 +1264,16 @@ class WechatLoginAndGuanshiRegisterView(APIView):
|
|||||||
openid = wechat_data['openid']
|
openid = wechat_data['openid']
|
||||||
kehuduan_ip = self._huoqu_kehuduan_ip(request)
|
kehuduan_ip = self._huoqu_kehuduan_ip(request)
|
||||||
|
|
||||||
|
from jituan.services.club_resolver import resolve_club_id_for_wechat_request
|
||||||
|
from jituan.services.club_user import ensure_user_club_id, resolve_or_create_wx_user
|
||||||
|
|
||||||
|
club_id = resolve_club_id_for_wechat_request(request)
|
||||||
|
|
||||||
with transaction.atomic():
|
with transaction.atomic():
|
||||||
user_main, created = User.objects.select_for_update().get_or_create(
|
user_main, created = resolve_or_create_wx_user(
|
||||||
OpenID=openid,
|
club_id, openid, self._shengcheng_yonghu_id,
|
||||||
defaults={
|
|
||||||
'UserUID': self._shengcheng_yonghu_id(),
|
|
||||||
'UserName': openid,
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
|
ensure_user_club_id(user_main, club_id)
|
||||||
user_main.IP = kehuduan_ip
|
user_main.IP = kehuduan_ip
|
||||||
user_main.UserLastLoginDate = timezone.now()
|
user_main.UserLastLoginDate = timezone.now()
|
||||||
user_main.save()
|
user_main.save()
|
||||||
|
|||||||
Reference in New Issue
Block a user