forum
This commit is contained in:
Binary file not shown.
@@ -1004,9 +1004,9 @@ def wechat_login(request):
|
|||||||
phone_number = None
|
phone_number = None
|
||||||
|
|
||||||
if phone_code:
|
if phone_code:
|
||||||
access_token = get_access_token(config)
|
try:
|
||||||
if access_token:
|
access_token = get_access_token(config)
|
||||||
try:
|
if access_token:
|
||||||
phone_url = f"https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token={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_res = requests.post(phone_url, json={'code': phone_code}, timeout=5)
|
||||||
phone_data = phone_res.json()
|
phone_data = phone_res.json()
|
||||||
@@ -1014,8 +1014,13 @@ def wechat_login(request):
|
|||||||
if phone_data.get('errcode') == 0:
|
if phone_data.get('errcode') == 0:
|
||||||
phone_info = phone_data.get('phone_info')
|
phone_info = phone_data.get('phone_info')
|
||||||
phone_number = phone_info.get('purePhoneNumber')
|
phone_number = phone_info.get('purePhoneNumber')
|
||||||
except Exception as e:
|
else:
|
||||||
print(f"获取手机号失败: {e}")
|
print(f"获取手机号API返回错误: {phone_data}")
|
||||||
|
else:
|
||||||
|
print("获取 AccessToken 失败,无法解密手机号")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"获取手机号异常: {str(e)}")
|
||||||
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
with transaction.atomic():
|
with transaction.atomic():
|
||||||
@@ -1029,29 +1034,41 @@ def wechat_login(request):
|
|||||||
|
|
||||||
if mp_user and phone_user:
|
if mp_user and phone_user:
|
||||||
if mp_user != phone_user:
|
if mp_user != phone_user:
|
||||||
# 【合并场景】: 小程序用户 和 手机号用户 都存在且不同 -> 将手机号用户(Web)合并到小程序用户
|
# 【合并场景】: 小程序用户 和 手机号用户 都存在且不同
|
||||||
# 注意: 如果 phone_user 也是真实的 MP 用户(有 openid 且不是 web_), 则可能冲突,这里默认保留当前登录的 mp_user
|
|
||||||
|
|
||||||
# 1. 迁移订单
|
# 检查 phone_user 是否已经是真实的 MP 用户 (防止覆盖已绑定的其他微信账号)
|
||||||
Order.objects.filter(wechat_user=phone_user).update(wechat_user=mp_user)
|
# 规则: 如果 phone_user.openid 不是以 'web_' 开头,说明它已经是一个微信用户
|
||||||
# 2. 迁移社区数据 (延迟导入避免循环引用)
|
# 此时我们不能简单的合并,因为这意味着两个不同的微信账号绑定了同一个手机号(可能是异常或用户更换了微信号)
|
||||||
from community.models import ActivitySignup, Topic, Reply
|
# 策略: 优先保留当前的 mp_user,提示用户手机号已被占用,或者这里简单处理为不合并手机号,只登录 mp_user
|
||||||
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()
|
|
||||||
|
|
||||||
# 删除旧用户
|
if not phone_user.openid.startswith('web_'):
|
||||||
phone_user.delete()
|
print(f"冲突: 手机号 {phone_number} 已被用户 {phone_user.id} (OpenID: {phone_user.openid}) 绑定,无法合并到当前用户 {mp_user.id}")
|
||||||
user = mp_user
|
# 这种情况下,我们让当前用户登录,但不更新手机号 (或者可以返回错误提示需人工解绑)
|
||||||
|
user = mp_user
|
||||||
# 更新手机号
|
# 也可以选择强制更新手机号到当前用户,并解绑旧用户(取决于业务规则,这里选择保守策略:不合并,仅登录)
|
||||||
if not user.phone_number:
|
else:
|
||||||
user.phone_number = phone_number
|
# 是 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()
|
||||||
|
|
||||||
|
# 删除旧用户
|
||||||
|
phone_user.delete()
|
||||||
|
user = mp_user
|
||||||
|
|
||||||
|
# 更新手机号
|
||||||
|
if not user.phone_number:
|
||||||
|
user.phone_number = phone_number
|
||||||
|
user.save()
|
||||||
else:
|
else:
|
||||||
# 同一个用户
|
# 同一个用户
|
||||||
user = mp_user
|
user = mp_user
|
||||||
@@ -1059,31 +1076,46 @@ def wechat_login(request):
|
|||||||
elif phone_user:
|
elif phone_user:
|
||||||
# 【绑定场景】: 只有手机号用户存在 (通常是 Web 用户) -> 升级为小程序用户
|
# 【绑定场景】: 只有手机号用户存在 (通常是 Web 用户) -> 升级为小程序用户
|
||||||
user = phone_user
|
user = phone_user
|
||||||
|
|
||||||
# 只有当它是 Web 虚拟用户时,才覆盖 OpenID
|
# 只有当它是 Web 虚拟用户时,才覆盖 OpenID
|
||||||
# 或者如果它就是目标用户,直接更新
|
|
||||||
if user.openid.startswith('web_') or not user.openid:
|
if user.openid.startswith('web_') or not user.openid:
|
||||||
user.openid = openid
|
user.openid = openid
|
||||||
|
user.save()
|
||||||
elif user.openid != openid:
|
elif user.openid != openid:
|
||||||
# 冲突: 手机号已被另一个真实 OpenID 绑定,但当前登录的是新的 OpenID
|
# 冲突: 手机号已被另一个真实 OpenID 绑定,但当前登录的是新的 OpenID
|
||||||
# 策略: 创建新用户,不合并 (避免安全风险)
|
# 策略: 创建新用户,不合并 (避免安全风险)
|
||||||
user = WeChatUser.objects.create(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:
|
elif mp_user:
|
||||||
# 【更新场景】: 只有小程序用户存在 -> 更新手机号
|
# 【更新场景】: 只有小程序用户存在 -> 更新手机号
|
||||||
user = mp_user
|
user = mp_user
|
||||||
if phone_number:
|
if phone_number:
|
||||||
|
# 检查手机号是否冲突 (理论上 phone_user 为 None 说明没有冲突)
|
||||||
user.phone_number = phone_number
|
user.phone_number = phone_number
|
||||||
|
user.save()
|
||||||
|
|
||||||
else:
|
else:
|
||||||
# 【新建场景】: 都不存在 -> 创建新用户
|
# 【新建场景】: 都不存在 -> 创建新用户
|
||||||
user = WeChatUser.objects.create(openid=openid)
|
user = WeChatUser.objects.create(openid=openid)
|
||||||
if phone_number:
|
if phone_number:
|
||||||
user.phone_number = phone_number
|
user.phone_number = phone_number
|
||||||
|
user.save()
|
||||||
|
|
||||||
# 统一更新会话信息
|
# 统一更新会话信息 (确保 user 对象是最新的)
|
||||||
user.session_key = session_key
|
# 重新获取对象以防状态不一致 (可选,但推荐)
|
||||||
user.unionid = unionid
|
# user.refresh_from_db()
|
||||||
user.save()
|
|
||||||
|
if user.openid == openid:
|
||||||
|
user.session_key = session_key
|
||||||
|
user.unionid = unionid
|
||||||
|
user.save()
|
||||||
|
|
||||||
created = False # 简化处理
|
created = False # 简化处理
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|||||||
@@ -61,6 +61,8 @@ export default function UserIndex() {
|
|||||||
const { code: loginCode } = await Taro.login()
|
const { code: loginCode } = await Taro.login()
|
||||||
|
|
||||||
// 2. 调用后端登录 (Code + PhoneCode)
|
// 2. 调用后端登录 (Code + PhoneCode)
|
||||||
|
console.log('loginCode:', loginCode)
|
||||||
|
console.log('phoneCode:', phoneCode)
|
||||||
const res = await Taro.request({
|
const res = await Taro.request({
|
||||||
url: 'https://market.quant-speed.com/api/wechat/login/',
|
url: 'https://market.quant-speed.com/api/wechat/login/',
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
|
|||||||
Reference in New Issue
Block a user