sync from local backup
This commit is contained in:
@@ -0,0 +1,284 @@
|
||||
from rest_framework import status
|
||||
from rest_framework.views import APIView
|
||||
from rest_framework.permissions import IsAuthenticated
|
||||
from rest_framework.parsers import JSONParser
|
||||
from rest_framework.pagination import PageNumberPagination
|
||||
from rest_framework.response import Response
|
||||
from django.db.models import Count, Q
|
||||
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
|
||||
|
||||
from utils.response_codes import ResponseCode, create_standardized_response, create_standardized_error_response
|
||||
from .models import Message, SystemMessage, SystemMessageRead
|
||||
from .serializers import MessageListSerializer, SystemMessageSerializer, SystemMessageDetailSerializer
|
||||
|
||||
|
||||
class MessagePagination(PageNumberPagination):
|
||||
page_size = 20
|
||||
page_size_query_param = 'page_size'
|
||||
max_page_size = 100
|
||||
|
||||
|
||||
class MessageListView(APIView):
|
||||
permission_classes = [IsAuthenticated]
|
||||
parser_classes = [JSONParser]
|
||||
|
||||
@swagger_auto_schema(
|
||||
tags=['消息'],
|
||||
operation_summary='获取消息列表',
|
||||
operation_description='获取当前用户的消息列表,支持按类型筛选: reply/at_me/like/system',
|
||||
manual_parameters=[
|
||||
openapi.Parameter('type', openapi.IN_QUERY, description='消息类型: reply/at_me/like/system', 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}
|
||||
)
|
||||
def get(self, request):
|
||||
msg_type = request.query_params.get('type', '')
|
||||
|
||||
if msg_type == 'system':
|
||||
queryset = SystemMessage.objects.all()
|
||||
paginator = MessagePagination()
|
||||
page = paginator.paginate_queryset(queryset, request)
|
||||
read_ids = set(
|
||||
SystemMessageRead.objects.filter(
|
||||
user=request.user,
|
||||
system_message__in=page
|
||||
).values_list('system_message_id', flat=True)
|
||||
)
|
||||
serializer = SystemMessageSerializer(page, many=True, context={'request': request, 'read_ids': read_ids})
|
||||
return create_standardized_response(data=paginator.get_paginated_response(serializer.data).data, code=ResponseCode.SUCCESS)
|
||||
|
||||
valid_types = ['reply', 'at_me', 'like']
|
||||
if msg_type and msg_type in valid_types:
|
||||
queryset = Message.objects.filter(recipient=request.user, msg_type=msg_type)
|
||||
else:
|
||||
queryset = Message.objects.filter(recipient=request.user)
|
||||
|
||||
paginator = MessagePagination()
|
||||
page = paginator.paginate_queryset(queryset, request)
|
||||
serializer = MessageListSerializer(page, many=True, context={'request': request})
|
||||
return create_standardized_response(data=paginator.get_paginated_response(serializer.data).data, code=ResponseCode.SUCCESS)
|
||||
|
||||
|
||||
class UnreadCountView(APIView):
|
||||
permission_classes = [IsAuthenticated]
|
||||
parser_classes = [JSONParser]
|
||||
|
||||
@swagger_auto_schema(
|
||||
tags=['消息'],
|
||||
operation_summary='获取未读消息数量',
|
||||
operation_description='获取当前用户各类型未读消息的数量统计',
|
||||
responses={200: success_response, 401: unauthorized_response}
|
||||
)
|
||||
def get(self, request):
|
||||
user = request.user
|
||||
message_counts = Message.objects.filter(
|
||||
recipient=user, is_read=False
|
||||
).values('msg_type').annotate(count=Count('id'))
|
||||
|
||||
counts = {'reply': 0, 'at_me': 0, 'like': 0}
|
||||
for item in message_counts:
|
||||
if item['msg_type'] in counts:
|
||||
counts[item['msg_type']] = item['count']
|
||||
|
||||
read_system_ids = SystemMessageRead.objects.filter(user=user).values_list('system_message_id', flat=True)
|
||||
system_unread = SystemMessage.objects.filter(is_global=True).exclude(id__in=read_system_ids).count()
|
||||
|
||||
counts['system'] = system_unread
|
||||
counts['total'] = counts['reply'] + counts['at_me'] + counts['like'] + counts['system']
|
||||
|
||||
return create_standardized_response(data=counts, code=ResponseCode.SUCCESS)
|
||||
|
||||
|
||||
class MessageReadView(APIView):
|
||||
permission_classes = [IsAuthenticated]
|
||||
parser_classes = [JSONParser]
|
||||
|
||||
@swagger_auto_schema(
|
||||
tags=['消息'],
|
||||
operation_summary='标记消息为已读',
|
||||
operation_description='将指定消息标记为已读,支持普通消息和系统消息',
|
||||
manual_parameters=[
|
||||
openapi.Parameter('pk', openapi.IN_PATH, description='消息ID', type=openapi.TYPE_INTEGER, required=True),
|
||||
],
|
||||
responses={200: success_response, 401: unauthorized_response, 404: not_found_response}
|
||||
)
|
||||
def post(self, request, pk):
|
||||
try:
|
||||
message = Message.objects.get(pk=pk, recipient=request.user)
|
||||
message.is_read = True
|
||||
message.save(update_fields=['is_read'])
|
||||
return create_standardized_response(data={'is_read': True}, code=ResponseCode.SUCCESS)
|
||||
except Message.DoesNotExist:
|
||||
pass
|
||||
|
||||
try:
|
||||
system_message = SystemMessage.objects.get(pk=pk)
|
||||
SystemMessageRead.objects.get_or_create(
|
||||
user=request.user,
|
||||
system_message=system_message
|
||||
)
|
||||
return create_standardized_response(data={'is_read': True}, code=ResponseCode.SUCCESS)
|
||||
except SystemMessage.DoesNotExist:
|
||||
return create_standardized_error_response(
|
||||
code=ResponseCode.NOT_FOUND,
|
||||
message='消息不存在',
|
||||
status_code=status.HTTP_404_NOT_FOUND
|
||||
)
|
||||
|
||||
|
||||
class MessageReadAllView(APIView):
|
||||
permission_classes = [IsAuthenticated]
|
||||
parser_classes = [JSONParser]
|
||||
|
||||
@swagger_auto_schema(
|
||||
tags=['消息'],
|
||||
operation_summary='全部标记为已读',
|
||||
operation_description='将指定类型或所有消息标记为已读',
|
||||
request_body=openapi.Schema(
|
||||
type=openapi.TYPE_OBJECT,
|
||||
properties={
|
||||
'type': openapi.Schema(type=openapi.TYPE_STRING, description='消息类型: reply/at_me/like/system,不传则标记全部'),
|
||||
}
|
||||
),
|
||||
responses={200: success_response, 401: unauthorized_response}
|
||||
)
|
||||
def post(self, request):
|
||||
msg_type = request.data.get('type', '')
|
||||
user = request.user
|
||||
affected = 0
|
||||
|
||||
if msg_type == 'system':
|
||||
system_messages = SystemMessage.objects.filter(is_global=True)
|
||||
for sm in system_messages:
|
||||
_, created = SystemMessageRead.objects.get_or_create(
|
||||
user=user,
|
||||
system_message=sm
|
||||
)
|
||||
if created:
|
||||
affected += 1
|
||||
elif msg_type and msg_type in ['reply', 'at_me', 'like']:
|
||||
affected = Message.objects.filter(
|
||||
recipient=user, msg_type=msg_type, is_read=False
|
||||
).update(is_read=True)
|
||||
else:
|
||||
affected = Message.objects.filter(
|
||||
recipient=user, is_read=False
|
||||
).update(is_read=True)
|
||||
|
||||
system_messages = SystemMessage.objects.filter(is_global=True)
|
||||
for sm in system_messages:
|
||||
_, created = SystemMessageRead.objects.get_or_create(
|
||||
user=user,
|
||||
system_message=sm
|
||||
)
|
||||
if created:
|
||||
affected += 1
|
||||
|
||||
return create_standardized_response(data={'affected': affected}, code=ResponseCode.SUCCESS)
|
||||
|
||||
|
||||
class MessageDeleteView(APIView):
|
||||
permission_classes = [IsAuthenticated]
|
||||
parser_classes = [JSONParser]
|
||||
|
||||
@swagger_auto_schema(
|
||||
tags=['消息'],
|
||||
operation_summary='删除消息',
|
||||
operation_description='删除指定消息,支持普通消息和系统消息',
|
||||
manual_parameters=[
|
||||
openapi.Parameter('pk', openapi.IN_PATH, description='消息ID', type=openapi.TYPE_INTEGER, required=True),
|
||||
],
|
||||
responses={204: '删除成功', 401: unauthorized_response, 404: not_found_response}
|
||||
)
|
||||
def delete(self, request, pk):
|
||||
try:
|
||||
message = Message.objects.get(pk=pk, recipient=request.user)
|
||||
message.delete()
|
||||
return Response(status=status.HTTP_204_NO_CONTENT)
|
||||
except Message.DoesNotExist:
|
||||
pass
|
||||
|
||||
try:
|
||||
system_message = SystemMessage.objects.get(pk=pk)
|
||||
SystemMessageRead.objects.get_or_create(
|
||||
user=request.user,
|
||||
system_message=system_message
|
||||
)
|
||||
return Response(status=status.HTTP_204_NO_CONTENT)
|
||||
except SystemMessage.DoesNotExist:
|
||||
return create_standardized_error_response(
|
||||
code=ResponseCode.NOT_FOUND,
|
||||
message='消息不存在',
|
||||
status_code=status.HTTP_404_NOT_FOUND
|
||||
)
|
||||
|
||||
|
||||
class MessageClearAllView(APIView):
|
||||
permission_classes = [IsAuthenticated]
|
||||
parser_classes = [JSONParser]
|
||||
|
||||
@swagger_auto_schema(
|
||||
tags=['消息'],
|
||||
operation_summary='清空所有消息',
|
||||
operation_description='删除指定类型或全部消息,可选类型: reply/at_me/like/system',
|
||||
request_body=openapi.Schema(
|
||||
type=openapi.TYPE_OBJECT,
|
||||
properties={
|
||||
'type': openapi.Schema(type=openapi.TYPE_STRING, description='消息类型: reply/at_me/like/system,不传则清空全部'),
|
||||
}
|
||||
),
|
||||
responses={200: success_response, 401: unauthorized_response}
|
||||
)
|
||||
def delete(self, request):
|
||||
msg_type = request.data.get('type', '')
|
||||
user = request.user
|
||||
deleted_count = 0
|
||||
|
||||
if msg_type == 'system':
|
||||
# 删除系统消息的已读记录(相当于清空系统消息)
|
||||
deleted_count = SystemMessageRead.objects.filter(user=user).delete()[0]
|
||||
elif msg_type and msg_type in ['reply', 'at_me', 'like']:
|
||||
deleted_count = Message.objects.filter(recipient=user, msg_type=msg_type).delete()[0]
|
||||
else:
|
||||
# 删除所有普通消息
|
||||
deleted_count = Message.objects.filter(recipient=user).delete()[0]
|
||||
# 同时删除所有系统消息已读记录
|
||||
deleted_count += SystemMessageRead.objects.filter(user=user).delete()[0]
|
||||
|
||||
return create_standardized_response(data={'deleted': deleted_count}, code=ResponseCode.SUCCESS)
|
||||
|
||||
|
||||
class SystemMessageDetailView(APIView):
|
||||
permission_classes = [IsAuthenticated]
|
||||
parser_classes = [JSONParser]
|
||||
|
||||
@swagger_auto_schema(
|
||||
tags=['消息'],
|
||||
operation_summary='获取系统消息详情',
|
||||
operation_description='获取指定系统消息的详细内容,并自动标记为已读',
|
||||
manual_parameters=[
|
||||
openapi.Parameter('pk', openapi.IN_PATH, description='系统消息ID', type=openapi.TYPE_INTEGER, required=True),
|
||||
],
|
||||
responses={200: success_response, 401: unauthorized_response, 404: not_found_response}
|
||||
)
|
||||
def get(self, request, pk):
|
||||
try:
|
||||
system_message = SystemMessage.objects.get(pk=pk)
|
||||
except SystemMessage.DoesNotExist:
|
||||
return create_standardized_error_response(
|
||||
code=ResponseCode.NOT_FOUND,
|
||||
message='系统消息不存在',
|
||||
status_code=status.HTTP_404_NOT_FOUND
|
||||
)
|
||||
|
||||
SystemMessageRead.objects.get_or_create(
|
||||
user=request.user,
|
||||
system_message=system_message
|
||||
)
|
||||
|
||||
serializer = SystemMessageDetailSerializer(system_message, context={'request': request})
|
||||
return create_standardized_response(data=serializer.data, code=ResponseCode.SUCCESS)
|
||||
Reference in New Issue
Block a user