This commit is contained in:
@@ -1016,6 +1016,15 @@ def wechat_login(request):
|
||||
phone_res = requests.post(phone_url, json={'code': phone_code}, timeout=5)
|
||||
phone_data = phone_res.json()
|
||||
|
||||
# Retry if access token is invalid or expired
|
||||
if phone_data.get('errcode') in [40001, 40014, 42001]:
|
||||
print(f"Access token invalid/expired ({phone_data.get('errcode')}), refreshing...")
|
||||
access_token = get_access_token(config, force_refresh=True)
|
||||
if access_token:
|
||||
phone_url = f"https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token={access_token}"
|
||||
phone_res = requests.post(phone_url, json={'code': phone_code}, timeout=5)
|
||||
phone_data = phone_res.json()
|
||||
|
||||
if phone_data.get('errcode') == 0:
|
||||
phone_info = phone_data.get('phone_info')
|
||||
phone_number = phone_info.get('purePhoneNumber')
|
||||
@@ -1066,14 +1075,21 @@ def wechat_login(request):
|
||||
dist.user = mp_user
|
||||
dist.save()
|
||||
|
||||
# 4. 迁移用户信息(如果小程序用户没有昵称/头像,继承Web用户的)
|
||||
if not mp_user.nickname and phone_user.nickname:
|
||||
# 4. 迁移用户信息(优先使用Web用户的信息,覆盖小程序的信息,保持体验一致)
|
||||
if phone_user.nickname:
|
||||
mp_user.nickname = phone_user.nickname
|
||||
if not mp_user.avatar_url and phone_user.avatar_url:
|
||||
if phone_user.avatar_url:
|
||||
mp_user.avatar_url = phone_user.avatar_url
|
||||
if mp_user.gender == 0 and phone_user.gender != 0:
|
||||
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徽章
|
||||
mp_user.has_web_badge = True
|
||||
mp_user.save()
|
||||
@@ -1096,6 +1112,8 @@ def wechat_login(request):
|
||||
# 只有当它是 Web 虚拟用户时,才覆盖 OpenID
|
||||
if user.openid.startswith('web_') or not user.openid:
|
||||
user.openid = openid
|
||||
# 确保标记为拥有 Web 徽章 (虽然它本来就是 Web 用户转过来的)
|
||||
user.has_web_badge = True
|
||||
user.save()
|
||||
elif user.openid != openid:
|
||||
# 冲突: 手机号已被另一个真实 OpenID 绑定,但当前登录的是新的 OpenID
|
||||
@@ -1134,8 +1152,20 @@ def wechat_login(request):
|
||||
# 更新用户基本信息 (如果有传入)
|
||||
if nickname:
|
||||
user.nickname = nickname
|
||||
elif not user.nickname:
|
||||
# 默认昵称逻辑 (与 Web 端保持一致)
|
||||
if user.phone_number:
|
||||
user.nickname = f"User_{user.phone_number[-4:]}"
|
||||
else:
|
||||
user.nickname = f"WeChat_User_{user.openid[-4:]}"
|
||||
|
||||
if avatar_url:
|
||||
user.avatar_url = avatar_url
|
||||
elif not user.avatar_url:
|
||||
# 默认头像逻辑
|
||||
seed = user.phone_number or user.openid
|
||||
user.avatar_url = f"https://api.dicebear.com/7.x/avataaars/svg?seed={seed}"
|
||||
|
||||
if gender is not None:
|
||||
user.gender = gender
|
||||
if country:
|
||||
@@ -1338,6 +1368,23 @@ def bind_phone(request):
|
||||
dist.user = current_user
|
||||
dist.save()
|
||||
|
||||
# 6. 迁移用户信息 (优先使用 Web 用户信息)
|
||||
if existing_user.nickname:
|
||||
current_user.nickname = existing_user.nickname
|
||||
if existing_user.avatar_url:
|
||||
current_user.avatar_url = existing_user.avatar_url
|
||||
if existing_user.gender != 0:
|
||||
current_user.gender = existing_user.gender
|
||||
|
||||
# 7. 迁移系统用户关联
|
||||
if existing_user.user and not current_user.user:
|
||||
current_user.user = existing_user.user
|
||||
existing_user.user = None
|
||||
existing_user.save()
|
||||
|
||||
# 8. 标记 Web 徽章
|
||||
current_user.has_web_badge = True
|
||||
|
||||
# 删除旧 Web 用户
|
||||
existing_user.delete()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user