@@ -0,0 +1,111 @@
|
||||
from django.contrib.auth import authenticate, login, logout
|
||||
from rest_framework import permissions, status
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.views import APIView
|
||||
|
||||
from .migration_service import apply_visitor_migration
|
||||
from .models import UserSession, VisitorMigration
|
||||
from .serializers import RegisterSerializer, UserSerializer
|
||||
|
||||
|
||||
def client_ip(request):
|
||||
forwarded = request.META.get("HTTP_X_FORWARDED_FOR")
|
||||
return forwarded.split(",")[0].strip() if forwarded else request.META.get("REMOTE_ADDR")
|
||||
|
||||
|
||||
class RegisterView(APIView):
|
||||
permission_classes = [permissions.AllowAny]
|
||||
|
||||
def post(self, request):
|
||||
serializer = RegisterSerializer(
|
||||
data=request.data,
|
||||
context={"ip_address": client_ip(request)},
|
||||
)
|
||||
serializer.is_valid(raise_exception=True)
|
||||
user = serializer.save()
|
||||
login(request, user)
|
||||
self._record_session(request, user)
|
||||
payload = UserSerializer(user).data
|
||||
payload["visitor_migration_pending"] = hasattr(user, "visitor_migration")
|
||||
return Response(payload, status=status.HTTP_201_CREATED)
|
||||
|
||||
@staticmethod
|
||||
def _record_session(request, user):
|
||||
if not request.session.session_key:
|
||||
request.session.save()
|
||||
UserSession.objects.update_or_create(
|
||||
session_key=request.session.session_key,
|
||||
defaults={
|
||||
"user": user,
|
||||
"user_agent": request.headers.get("User-Agent", "")[:300],
|
||||
"ip_address": client_ip(request),
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
class LoginView(APIView):
|
||||
permission_classes = [permissions.AllowAny]
|
||||
|
||||
def post(self, request):
|
||||
user = authenticate(
|
||||
request,
|
||||
username=request.data.get("username", ""),
|
||||
password=request.data.get("password", ""),
|
||||
)
|
||||
if user is None or not user.is_active:
|
||||
return Response(
|
||||
{"error": {"code": "invalid_credentials", "message": "用户名或密码错误"}},
|
||||
status=status.HTTP_400_BAD_REQUEST,
|
||||
)
|
||||
login(request, user)
|
||||
RegisterView._record_session(request, user)
|
||||
return Response(UserSerializer(user).data)
|
||||
|
||||
|
||||
class LogoutView(APIView):
|
||||
def post(self, request):
|
||||
if request.session.session_key:
|
||||
UserSession.objects.filter(session_key=request.session.session_key).delete()
|
||||
logout(request)
|
||||
return Response(status=status.HTTP_204_NO_CONTENT)
|
||||
|
||||
|
||||
class MeView(APIView):
|
||||
def get(self, request):
|
||||
return Response(UserSerializer(request.user).data)
|
||||
|
||||
def patch(self, request):
|
||||
serializer = UserSerializer(request.user, data=request.data, partial=True)
|
||||
serializer.is_valid(raise_exception=True)
|
||||
serializer.save()
|
||||
return Response(serializer.data)
|
||||
|
||||
|
||||
class VisitorMigrationView(APIView):
|
||||
def get(self, request):
|
||||
migration = VisitorMigration.objects.filter(user=request.user).first()
|
||||
if migration is None:
|
||||
return Response({"pending": False, "summary": {}})
|
||||
return Response(
|
||||
{
|
||||
"pending": migration.status == VisitorMigration.Status.PENDING,
|
||||
"status": migration.status,
|
||||
"summary": migration.summary,
|
||||
}
|
||||
)
|
||||
|
||||
def post(self, request):
|
||||
migration = VisitorMigration.objects.filter(user=request.user).first()
|
||||
if migration is None:
|
||||
return Response(
|
||||
{"error": {"code": "no_visitor_data", "message": "没有待迁移的游客数据"}},
|
||||
status=status.HTTP_404_NOT_FOUND,
|
||||
)
|
||||
migration = apply_visitor_migration(request.user)
|
||||
return Response(
|
||||
{
|
||||
"pending": False,
|
||||
"status": migration.status,
|
||||
"summary": migration.summary,
|
||||
}
|
||||
)
|
||||
Reference in New Issue
Block a user