修复手机号认证完成后仍反复弹窗的问题
认证提交接口在仅上传头像时错误返回成功,检查接口也未兼容已有手机号的老数据。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -252,10 +252,24 @@ class CheckPhoneAuthView(APIView):
|
||||
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
def post(self, request):
|
||||
user = request.user
|
||||
@staticmethod
|
||||
def _phone_auth_completed(user):
|
||||
"""是否已完成手机号认证(兼容 PhoneVerified 未写入的老数据)。"""
|
||||
if bool(getattr(user, 'PhoneVerified', False)):
|
||||
return True
|
||||
phone = (getattr(user, 'Phone', None) or '').strip()
|
||||
return len(phone) >= 11
|
||||
|
||||
if getattr(user, 'PhoneVerified', False):
|
||||
def post(self, request):
|
||||
uid = getattr(request.user, 'UserUID', None)
|
||||
user = request.user
|
||||
if uid:
|
||||
try:
|
||||
user = User.query.get(UserUID=uid)
|
||||
except User.DoesNotExist:
|
||||
user = request.user
|
||||
|
||||
if self._phone_auth_completed(user):
|
||||
return Response({'code': 0, 'need_auth': False})
|
||||
|
||||
if self._dashou_meets_threshold(user):
|
||||
|
||||
@@ -164,6 +164,7 @@ def huoquKehuduanIP(request):
|
||||
|
||||
class UserInfoUpdateView(APIView):
|
||||
permission_classes = [permissions.IsAuthenticated]
|
||||
parser_classes = [MultiPartParser, FormParser, JSONParser]
|
||||
|
||||
# 进程内缓存,防止同一code被重复调用微信(单进程安全,多进程小概率重复,但用户极少可忽略)
|
||||
_phone_cache = {}
|
||||
@@ -173,6 +174,7 @@ class UserInfoUpdateView(APIView):
|
||||
user = request.user
|
||||
boss = self._get_or_create_boss(user)
|
||||
result = {}
|
||||
nick = request.data.get('nicheng')
|
||||
|
||||
# 诊断日志:记录入参和实例状态
|
||||
logger.warning(
|
||||
@@ -201,7 +203,6 @@ class UserInfoUpdateView(APIView):
|
||||
return Response({'code': 2, 'msg': '头像上传失败', 'data': None}, status=500)
|
||||
|
||||
# 昵称
|
||||
nick = request.data.get('nicheng')
|
||||
if nick:
|
||||
nick = str(nick).strip()
|
||||
if len(nick) > 20:
|
||||
@@ -209,9 +210,28 @@ class UserInfoUpdateView(APIView):
|
||||
boss.nickname = nick
|
||||
result['nicheng'] = nick
|
||||
|
||||
# 手机号 —— 失败不阻塞其他字段(头像/昵称)的保存
|
||||
code = request.data.get('shoujihao_code')
|
||||
# 手机号 —— multipart 表单字段兼容 request.data / request.POST
|
||||
code = (
|
||||
request.data.get('shoujihao_code')
|
||||
or request.POST.get('shoujihao_code')
|
||||
or ''
|
||||
)
|
||||
if isinstance(code, str):
|
||||
code = code.strip()
|
||||
else:
|
||||
code = str(code or '').strip()
|
||||
|
||||
# 认证页仅上传头像+手机号,不带昵称
|
||||
is_phone_auth_flow = bool(av) and not nick
|
||||
phone_error = None
|
||||
|
||||
if is_phone_auth_flow and not code:
|
||||
return Response({
|
||||
'code': 6,
|
||||
'msg': '未收到手机号授权,请重新点击获取手机号',
|
||||
'data': None,
|
||||
}, status=200)
|
||||
|
||||
if code:
|
||||
phone = self._get_phone_safe(code, request)
|
||||
if phone is None:
|
||||
@@ -220,6 +240,7 @@ class UserInfoUpdateView(APIView):
|
||||
user.Phone = phone
|
||||
user.PhoneVerified = True
|
||||
result['phone'] = phone
|
||||
result['phone_verified'] = True
|
||||
|
||||
if not result and not phone_error:
|
||||
logger.warning("[USERINFO_XIUGAI] 无更新,result 为空")
|
||||
@@ -237,15 +258,36 @@ class UserInfoUpdateView(APIView):
|
||||
phone_error,
|
||||
)
|
||||
|
||||
# 有字段更新时先保存(即使手机号失败,头像/昵称也应入库)
|
||||
# 认证流:必须拿到手机号才算成功,避免只存头像却返回 code=0 导致反复弹窗
|
||||
if is_phone_auth_flow and 'phone' not in result:
|
||||
msg = phone_error or '手机号获取失败,请重新授权'
|
||||
if result:
|
||||
with transaction.atomic():
|
||||
user_update_fields = []
|
||||
if 'touxiang' in result:
|
||||
user_update_fields.append('Avatar')
|
||||
if user_update_fields:
|
||||
user.save(update_fields=user_update_fields)
|
||||
if 'nicheng' in result:
|
||||
boss.save()
|
||||
return Response({'code': 6, 'msg': msg, 'data': result or None}, status=200)
|
||||
|
||||
# 有字段更新时先保存(资料编辑:手机号失败不阻塞头像/昵称)
|
||||
if result:
|
||||
user_update_fields = []
|
||||
if 'touxiang' in result:
|
||||
user_update_fields.append('Avatar')
|
||||
if 'phone' in result:
|
||||
user_update_fields.extend(['Phone', 'PhoneVerified'])
|
||||
with transaction.atomic():
|
||||
user.save()
|
||||
if user_update_fields:
|
||||
user.save(update_fields=user_update_fields)
|
||||
elif result:
|
||||
user.save()
|
||||
boss.save()
|
||||
logger.warning("[USERINFO_XIUGAI] 保存成功 result_keys=%s", list(result.keys()))
|
||||
|
||||
if phone_error:
|
||||
# 其他字段已保存,但手机号失败 —— 返回已保存的字段供前端更新缓存
|
||||
return Response({'code': 6, 'msg': phone_error, 'data': result}, status=200)
|
||||
|
||||
return Response({'code': 0, 'msg': '更新成功', 'data': result})
|
||||
|
||||
Reference in New Issue
Block a user