""" 用户模块视图 - App端用户 """ from rest_framework import viewsets, status from rest_framework.decorators import action from rest_framework.permissions import AllowAny, IsAuthenticated from rest_framework_simplejwt.tokens import RefreshToken from utils.response import success, error from apps.admins.authentication import AppJWTAuthentication from .models import User from .serializers import ( UserSerializer, UserDetailSerializer, PhoneLoginSerializer, UpdateUserSerializer ) def get_app_tokens(user): """ 为App用户生成JWT Token 在token中添加 user_type='app' 以区分管理员 """ refresh = RefreshToken.for_user(user) # 添加自定义声明 refresh['user_type'] = 'app' refresh['phone'] = user.phone return { 'access': str(refresh.access_token), 'refresh': str(refresh), } class AuthViewSet(viewsets.ViewSet): """认证视图集 - App端""" permission_classes = [AllowAny] @action(detail=False, methods=['post'], url_path='phone-login') def phone_login(self, request): """ 手机号一键登录 POST /api/v1/auth/phone-login """ serializer = PhoneLoginSerializer(data=request.data) if not serializer.is_valid(): return error(message=str(serializer.errors)) phone = serializer.validated_data['phone'] # 获取或创建用户 user, created = User.objects.get_or_create( phone=phone, defaults={'nickname': f'用户{phone[-4:]}'} ) if not user.is_active: return error(code=101, message='账号已被禁用') # 生成JWT Token(带user_type='app'标识) tokens = get_app_tokens(user) return success(data={ 'user': UserSerializer(user).data, 'token': tokens, 'is_new_user': created }, message='登录成功') @action(detail=False, methods=['post'], url_path='refresh') def refresh_token(self, request): """ 刷新Token POST /api/v1/auth/refresh """ refresh_token = request.data.get('refresh') if not refresh_token: return error(message='refresh token不能为空') try: refresh = RefreshToken(refresh_token) # 验证是否为app token user_type = refresh.get('user_type', 'app') if user_type not in ['app', None]: return error(code=103, message='无效的用户Token') return success(data={ 'access': str(refresh.access_token), 'refresh': str(refresh), }) except Exception as e: return error(code=103, message='Token已过期或无效') class UserViewSet(viewsets.ViewSet): """用户视图集 - App端""" authentication_classes = [AppJWTAuthentication] permission_classes = [IsAuthenticated] @action(detail=False, methods=['get']) def me(self, request): """ 获取当前用户信息 GET /api/v1/users/me """ return success(data=UserSerializer(request.user).data) @action(detail=False, methods=['put']) def update_me(self, request): """ 更新当前用户信息 PUT /api/v1/users/update_me """ serializer = UpdateUserSerializer(request.user, data=request.data, partial=True) if serializer.is_valid(): serializer.save() return success(data=UserSerializer(request.user).data, message='更新成功') return error(message=str(serializer.errors))