151 lines
5.7 KiB
Python
151 lines
5.7 KiB
Python
from adrf.views import APIView
|
|
from rest_framework.response import Response
|
|
from rest_framework import status
|
|
from django.db.models import Q
|
|
from asgiref.sync import sync_to_async
|
|
from ..models import Blacklist, FUser
|
|
from ..serializers.user_serializers import BlacklistSerializer
|
|
from utils.response_codes import (
|
|
ResponseCode,
|
|
create_standardized_response,
|
|
create_standardized_error_response
|
|
)
|
|
from drf_yasg.utils import swagger_auto_schema
|
|
from drf_yasg import openapi
|
|
from chunyu_project.common_schemas import success_response, error_response, unauthorized_response, not_found_response
|
|
|
|
|
|
class BlacklistListAPIView(APIView):
|
|
@swagger_auto_schema(
|
|
tags=['黑名单'],
|
|
operation_summary='获取黑名单列表',
|
|
operation_description='获取当前用户的黑名单列表,支持搜索和分页',
|
|
manual_parameters=[
|
|
openapi.Parameter('search', openapi.IN_QUERY, description='搜索关键词', type=openapi.TYPE_STRING),
|
|
openapi.Parameter('page', openapi.IN_QUERY, description='页码', type=openapi.TYPE_INTEGER),
|
|
openapi.Parameter('page_size', openapi.IN_QUERY, description='每页数量', type=openapi.TYPE_INTEGER),
|
|
],
|
|
responses={200: success_response, 401: unauthorized_response},
|
|
)
|
|
async def get(self, request):
|
|
queryset = Blacklist.objects.filter(user=request.user).select_related('blocked_user')
|
|
|
|
search = request.query_params.get('search', '')
|
|
if search:
|
|
queryset = queryset.filter(
|
|
Q(blocked_user__username__icontains=search) |
|
|
Q(blocked_user__email__icontains=search) |
|
|
Q(reason__icontains=search)
|
|
)
|
|
|
|
page = int(request.query_params.get('page', 1))
|
|
page_size = int(request.query_params.get('page_size', 10))
|
|
total = await queryset.acount()
|
|
start = (page - 1) * page_size
|
|
end = start + page_size
|
|
|
|
items = [item async for item in queryset[start:end]]
|
|
serializer = BlacklistSerializer(items, many=True)
|
|
|
|
return create_standardized_response(
|
|
data={
|
|
'results': await serializer.adata,
|
|
'total': total,
|
|
'page': page,
|
|
'page_size': page_size,
|
|
'total_pages': (total + page_size - 1) // page_size
|
|
},
|
|
code=ResponseCode.SUCCESS,
|
|
status_code=status.HTTP_200_OK
|
|
)
|
|
|
|
|
|
class BlacklistAddAPIView(APIView):
|
|
@swagger_auto_schema(
|
|
tags=['黑名单'],
|
|
operation_summary='添加黑名单',
|
|
operation_description='将指定用户添加到黑名单',
|
|
request_body=BlacklistSerializer,
|
|
responses={201: success_response, 400: error_response, 401: unauthorized_response},
|
|
)
|
|
async def post(self, request):
|
|
serializer = BlacklistSerializer(
|
|
data=request.data,
|
|
context={'request': request}
|
|
)
|
|
|
|
# 校验器内部含同步 ORM 查询(validate_blocked_user_id / validate),线程池兜底
|
|
if not await sync_to_async(serializer.is_valid)():
|
|
errors = serializer.errors
|
|
first_error = ''
|
|
for field, msgs in errors.items():
|
|
if isinstance(msgs, list) and msgs:
|
|
first_error = str(msgs[0])
|
|
break
|
|
|
|
return create_standardized_error_response(
|
|
data=errors,
|
|
code=ResponseCode.PARAMETER_ERROR,
|
|
message=first_error or '参数异常',
|
|
status_code=status.HTTP_400_BAD_REQUEST
|
|
)
|
|
|
|
blacklist = await serializer.asave()
|
|
result_serializer = BlacklistSerializer(blacklist)
|
|
|
|
return create_standardized_response(
|
|
data=await result_serializer.adata,
|
|
code=ResponseCode.SUCCESS,
|
|
status_code=status.HTTP_201_CREATED
|
|
)
|
|
|
|
|
|
class BlacklistCheckAPIView(APIView):
|
|
@swagger_auto_schema(
|
|
tags=['黑名单'],
|
|
operation_summary='检查用户是否在黑名单中',
|
|
operation_description='检查指定用户是否被当前用户加入黑名单',
|
|
manual_parameters=[
|
|
openapi.Parameter('user_id', openapi.IN_PATH, description='用户ID', type=openapi.TYPE_INTEGER),
|
|
],
|
|
responses={200: success_response, 401: unauthorized_response},
|
|
)
|
|
async def get(self, request, user_id):
|
|
is_blocked = await Blacklist.objects.filter(
|
|
user=request.user,
|
|
blocked_user_id=user_id
|
|
).aexists()
|
|
return create_standardized_response(
|
|
data={'is_blocked': is_blocked},
|
|
code=ResponseCode.SUCCESS,
|
|
status_code=status.HTTP_200_OK
|
|
)
|
|
|
|
|
|
class BlacklistRemoveAPIView(APIView):
|
|
@swagger_auto_schema(
|
|
tags=['黑名单'],
|
|
operation_summary='移除黑名单',
|
|
operation_description='将指定用户从黑名单中移除',
|
|
manual_parameters=[
|
|
openapi.Parameter('pk', openapi.IN_PATH, description='黑名单记录ID', type=openapi.TYPE_INTEGER),
|
|
],
|
|
responses={200: success_response, 401: unauthorized_response, 404: not_found_response},
|
|
)
|
|
async def delete(self, request, pk):
|
|
try:
|
|
blacklist = await Blacklist.objects.aget(id=pk, user=request.user)
|
|
except Blacklist.DoesNotExist:
|
|
return create_standardized_error_response(
|
|
code=ResponseCode.NOT_FOUND,
|
|
message='黑名单记录不存在',
|
|
status_code=status.HTTP_404_NOT_FOUND
|
|
)
|
|
|
|
await blacklist.adelete()
|
|
|
|
return create_standardized_response(
|
|
data={'deleted': True},
|
|
code=ResponseCode.SUCCESS,
|
|
status_code=status.HTTP_200_OK
|
|
) |