This commit is contained in:
@@ -1049,82 +1049,65 @@ def wechat_login(request):
|
||||
if mp_user and phone_user:
|
||||
if mp_user != phone_user:
|
||||
# 【合并场景】: 小程序用户 和 手机号用户 都存在且不同
|
||||
# 规则: 只要手机号一致,强制合并。以当前 OpenID (mp_user) 为准,吸纳旧用户 (phone_user) 的数据。
|
||||
|
||||
# 检查 phone_user 是否已经是真实的 MP 用户 (防止覆盖已绑定的其他微信账号)
|
||||
# 规则: 如果 phone_user.openid 不是以 'web_' 开头,说明它已经是一个微信用户
|
||||
# 此时我们不能简单的合并,因为这意味着两个不同的微信账号绑定了同一个手机号(可能是异常或用户更换了微信号)
|
||||
# 策略: 优先保留当前的 mp_user,提示用户手机号已被占用,或者这里简单处理为不合并手机号,只登录 mp_user
|
||||
# 1. 迁移订单
|
||||
Order.objects.filter(wechat_user=phone_user).update(wechat_user=mp_user)
|
||||
|
||||
if not phone_user.openid.startswith('web_'):
|
||||
print(f"冲突: 手机号 {phone_number} 已被用户 {phone_user.id} (OpenID: {phone_user.openid}) 绑定,无法合并到当前用户 {mp_user.id}")
|
||||
# 这种情况下,我们让当前用户登录,但不更新手机号 (或者可以返回错误提示需人工解绑)
|
||||
user = mp_user
|
||||
# 也可以选择强制更新手机号到当前用户,并解绑旧用户(取决于业务规则,这里选择保守策略:不合并,仅登录)
|
||||
else:
|
||||
# 是 Web 虚拟用户,可以安全合并
|
||||
# 1. 迁移订单
|
||||
Order.objects.filter(wechat_user=phone_user).update(wechat_user=mp_user)
|
||||
# 2. 迁移社区数据 (延迟导入避免循环引用)
|
||||
from community.models import ActivitySignup, Topic, Reply
|
||||
ActivitySignup.objects.filter(user=phone_user).update(user=mp_user)
|
||||
Topic.objects.filter(author=phone_user).update(author=mp_user)
|
||||
Reply.objects.filter(author=phone_user).update(author=mp_user)
|
||||
# 3. 迁移分销员
|
||||
if hasattr(phone_user, 'distributor') and not hasattr(mp_user, 'distributor'):
|
||||
dist = phone_user.distributor
|
||||
dist.user = mp_user
|
||||
dist.save()
|
||||
|
||||
# 4. 迁移用户信息(优先使用Web用户的信息,覆盖小程序的信息,保持体验一致)
|
||||
if phone_user.nickname:
|
||||
mp_user.nickname = phone_user.nickname
|
||||
if phone_user.avatar_url:
|
||||
mp_user.avatar_url = phone_user.avatar_url
|
||||
if phone_user.gender != 0:
|
||||
mp_user.gender = phone_user.gender
|
||||
|
||||
# 迁移关联的系统用户 (用于管理员权限等)
|
||||
if phone_user.user and not mp_user.user:
|
||||
mp_user.user = phone_user.user
|
||||
# 清除旧对象的关联,防止唯一约束冲突(虽然即将删除,但为了安全)
|
||||
phone_user.user = None
|
||||
phone_user.save()
|
||||
|
||||
# 标记拥有Web徽章
|
||||
# 2. 迁移社区数据 (延迟导入避免循环引用)
|
||||
from community.models import ActivitySignup, Topic, Reply
|
||||
ActivitySignup.objects.filter(user=phone_user).update(user=mp_user)
|
||||
Topic.objects.filter(author=phone_user).update(author=mp_user)
|
||||
Reply.objects.filter(author=phone_user).update(author=mp_user)
|
||||
|
||||
# 3. 迁移分销员
|
||||
if hasattr(phone_user, 'distributor') and not hasattr(mp_user, 'distributor'):
|
||||
dist = phone_user.distributor
|
||||
dist.user = mp_user
|
||||
dist.save()
|
||||
|
||||
# 4. 迁移用户信息
|
||||
# 如果 mp_user 尚未设置昵称头像(新用户),则沿用 phone_user 的
|
||||
if not mp_user.nickname and phone_user.nickname:
|
||||
mp_user.nickname = phone_user.nickname
|
||||
if not mp_user.avatar_url and phone_user.avatar_url:
|
||||
mp_user.avatar_url = phone_user.avatar_url
|
||||
if mp_user.gender == 0 and phone_user.gender != 0:
|
||||
mp_user.gender = phone_user.gender
|
||||
|
||||
# 迁移关联的系统用户 (用于管理员权限等)
|
||||
if phone_user.user and not mp_user.user:
|
||||
mp_user.user = phone_user.user
|
||||
phone_user.user = None
|
||||
phone_user.save()
|
||||
|
||||
# 标记拥有Web徽章 (如果旧用户是 Web 用户)
|
||||
if phone_user.openid.startswith('web_') or phone_user.has_web_badge:
|
||||
mp_user.has_web_badge = True
|
||||
mp_user.save()
|
||||
|
||||
# 删除旧用户
|
||||
phone_user.delete()
|
||||
user = mp_user
|
||||
|
||||
# 更新手机号
|
||||
user.phone_number = phone_number
|
||||
user.save()
|
||||
|
||||
# 更新手机号
|
||||
mp_user.phone_number = phone_number
|
||||
mp_user.save()
|
||||
|
||||
# 删除旧用户
|
||||
phone_user.delete()
|
||||
user = mp_user
|
||||
else:
|
||||
# 同一个用户
|
||||
user = mp_user
|
||||
|
||||
elif phone_user:
|
||||
# 【绑定场景】: 只有手机号用户存在 (通常是 Web 用户) -> 升级为小程序用户
|
||||
# 【绑定场景】: 只有手机号用户存在
|
||||
# 无论是否 Web 用户,只要 OpenID 不同,都更新为最新的 OpenID
|
||||
user = phone_user
|
||||
|
||||
# 只有当它是 Web 虚拟用户时,才覆盖 OpenID
|
||||
if user.openid.startswith('web_') or not user.openid:
|
||||
user.openid = openid
|
||||
# 确保标记为拥有 Web 徽章 (虽然它本来就是 Web 用户转过来的)
|
||||
if user.openid.startswith('web_'):
|
||||
user.has_web_badge = True
|
||||
|
||||
if user.openid != openid:
|
||||
print(f"用户更换 OpenID: {user.openid} -> {openid}, Phone: {phone_number}")
|
||||
user.openid = openid
|
||||
user.save()
|
||||
elif user.openid != openid:
|
||||
# 冲突: 手机号已被另一个真实 OpenID 绑定,但当前登录的是新的 OpenID
|
||||
# 策略: 创建新用户,不合并 (避免安全风险)
|
||||
# 检查 openid 是否已被其他用户占用 (理论上 mp_user 为 None 说明没有,但双重检查)
|
||||
existing_openid_user = WeChatUser.objects.filter(openid=openid).first()
|
||||
if existing_openid_user:
|
||||
user = existing_openid_user
|
||||
else:
|
||||
user = WeChatUser.objects.create(openid=openid)
|
||||
# 此时不绑定手机号,因为手机号被 phone_user 占用了
|
||||
|
||||
elif mp_user:
|
||||
# 【更新场景】: 只有小程序用户存在 -> 更新手机号
|
||||
@@ -1345,12 +1328,8 @@ def bind_phone(request):
|
||||
return Response({'message': '已绑定该手机号'})
|
||||
|
||||
# 发现冲突,需要合并
|
||||
# 策略:保留 current_user (MP User, with real OpenID),合并 existing_user (Web User) 的数据
|
||||
# 仅当 existing_user 是 Web 用户 (openid startswith 'web_') 时才合并
|
||||
# 如果 existing_user 也是 MP 用户 (real openid),则提示冲突,不允许绑定
|
||||
|
||||
if not existing_user.openid.startswith('web_'):
|
||||
return Response({'error': '该手机号已被其他微信账号绑定,无法重复绑定'}, status=status.HTTP_409_CONFLICT)
|
||||
# 策略:保留 current_user (MP User, with real OpenID),合并 existing_user (Phone User) 的数据
|
||||
# 无论 existing_user 是否是 Web 用户,都允许合并,以 current_user 为主(覆盖旧 OpenID)
|
||||
|
||||
# 执行合并
|
||||
from django.db import transaction
|
||||
@@ -1364,18 +1343,18 @@ def bind_phone(request):
|
||||
Topic.objects.filter(author=existing_user).update(author=current_user)
|
||||
# 4. 迁移 Reply
|
||||
Reply.objects.filter(author=existing_user).update(author=current_user)
|
||||
# 5. 迁移 Distributor (如果 Web 用户注册了分销员,且 MP 用户未注册)
|
||||
# 5. 迁移 Distributor (如果旧用户注册了分销员,且新用户未注册)
|
||||
if hasattr(existing_user, 'distributor') and not hasattr(current_user, 'distributor'):
|
||||
dist = existing_user.distributor
|
||||
dist.user = current_user
|
||||
dist.save()
|
||||
|
||||
# 6. 迁移用户信息 (优先使用 Web 用户信息)
|
||||
if existing_user.nickname:
|
||||
# 6. 迁移用户信息 (如果新用户尚未设置,则使用旧用户的信息)
|
||||
if not current_user.nickname and existing_user.nickname:
|
||||
current_user.nickname = existing_user.nickname
|
||||
if existing_user.avatar_url:
|
||||
if not current_user.avatar_url and existing_user.avatar_url:
|
||||
current_user.avatar_url = existing_user.avatar_url
|
||||
if existing_user.gender != 0:
|
||||
if current_user.gender == 0 and existing_user.gender != 0:
|
||||
current_user.gender = existing_user.gender
|
||||
|
||||
# 7. 迁移系统用户关联
|
||||
@@ -1384,10 +1363,11 @@ def bind_phone(request):
|
||||
existing_user.user = None
|
||||
existing_user.save()
|
||||
|
||||
# 8. 标记 Web 徽章
|
||||
current_user.has_web_badge = True
|
||||
# 8. 标记 Web 徽章 (如果旧用户是 Web 用户或已有徽章)
|
||||
if existing_user.openid.startswith('web_') or existing_user.has_web_badge:
|
||||
current_user.has_web_badge = True
|
||||
|
||||
# 删除旧 Web 用户
|
||||
# 删除旧用户
|
||||
existing_user.delete()
|
||||
|
||||
# 更新当前用户手机号
|
||||
|
||||
Reference in New Issue
Block a user