Files
chunyu_project/bug/views.py
T

170 lines
7.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
from rest_framework import status
from rest_framework.response import Response
from rest_framework.parsers import MultiPartParser, FormParser, JSONParser
from asgiref.sync import sync_to_async
from django.utils import timezone
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 adrf import generics
from .models import BugReport, BugReportComment
from .serializers import (
BugReportListSerializer,
BugReportDetailSerializer,
BugReportCreateSerializer,
BugReportCommentCreateSerializer,
BugReportCommentSerializer,
)
from utils.response_codes import ResponseCode, create_standardized_response, create_standardized_error_response
class BugReportListCreateAPIView(generics.ListCreateAPIView):
parser_classes = [JSONParser, MultiPartParser, FormParser]
def get_serializer_class(self):
if self.request.method == 'POST':
return BugReportCreateSerializer
return BugReportListSerializer
def get_queryset(self):
if getattr(self, 'swagger_fake_view', False):
return BugReport.objects.none()
return BugReport.objects.filter(user=self.request.user)
@swagger_auto_schema(
tags=['反馈'],
operation_summary='获取Bug反馈列表',
operation_description='获取当前用户提交的所有Bug反馈列表',
responses={200: success_response, 401: unauthorized_response}
)
async def list(self, request, *args, **kwargs):
queryset = self.get_queryset()
items = [x async for x in queryset]
serializer = self.get_serializer(items, many=True)
# 兜底:user_name 触发 user 外键懒加载、images_count 内部有同步 ORM count()
data = await sync_to_async(lambda: serializer.data)()
return create_standardized_response(
code=ResponseCode.SUCCESS,
data=data,
message='获取Bug反馈列表成功'
)
@swagger_auto_schema(
tags=['反馈'],
operation_summary='提交Bug反馈',
operation_description='提交新的Bug反馈,支持上传图片和附件',
request_body=BugReportCreateSerializer,
responses={201: success_response, 400: error_response, 401: unauthorized_response}
)
async def create(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
is_valid = await sync_to_async(serializer.is_valid)()
if is_valid:
# 兜底:serializer.create 内部有同步 ORM(BugReport/BugReportImage/BugReportAttachment 的 create)
bug_report = await sync_to_async(serializer.save)(user=request.user)
detail_serializer = BugReportDetailSerializer(bug_report)
# 兜底:detail 序列化会触发 user/images/attachments/comments 的同步懒加载
data = await sync_to_async(lambda: detail_serializer.data)()
return create_standardized_response(
code=ResponseCode.SUCCESS,
data=data,
message='Bug反馈提交成功',
status_code=status.HTTP_201_CREATED
)
return create_standardized_error_response(
code=ResponseCode.VALIDATION_ERROR,
data=serializer.errors,
message='提交失败',
status_code=status.HTTP_400_BAD_REQUEST
)
class BugReportDetailAPIView(generics.RetrieveAPIView):
serializer_class = BugReportDetailSerializer
parser_classes = [JSONParser, MultiPartParser]
def get_queryset(self):
if getattr(self, 'swagger_fake_view', False):
return BugReport.objects.none()
return BugReport.objects.filter(user=self.request.user)
@swagger_auto_schema(
tags=['反馈'],
operation_summary='获取Bug反馈详情',
operation_description='获取指定Bug反馈的详细信息,包括评论和附件',
manual_parameters=[
openapi.Parameter('pk', openapi.IN_PATH, description='Bug反馈ID', type=openapi.TYPE_INTEGER, required=True),
],
responses={200: success_response, 401: unauthorized_response, 404: not_found_response}
)
async def retrieve(self, request, *args, **kwargs):
try:
instance = await self.get_object()
serializer = self.get_serializer(instance)
# 兜底:detail 序列化会触发 user/images/attachments/comments 的同步懒加载
data = await sync_to_async(lambda: serializer.data)()
return create_standardized_response(
code=ResponseCode.SUCCESS,
data=data,
message='获取Bug反馈详情成功'
)
except BugReport.DoesNotExist:
return create_standardized_error_response(
code=ResponseCode.NOT_FOUND,
message='Bug反馈不存在',
status_code=status.HTTP_404_NOT_FOUND
)
class BugReportCommentCreateAPIView(generics.CreateAPIView):
serializer_class = BugReportCommentCreateSerializer
parser_classes = [JSONParser, MultiPartParser]
@swagger_auto_schema(
tags=['反馈'],
operation_summary='回复Bug反馈',
operation_description='为指定Bug反馈添加评论回复,支持上传图片和附件',
manual_parameters=[
openapi.Parameter('bug_report_id', openapi.IN_PATH, description='Bug反馈ID', type=openapi.TYPE_INTEGER, required=True),
],
request_body=BugReportCommentCreateSerializer,
responses={201: success_response, 400: error_response, 401: unauthorized_response, 404: not_found_response}
)
async def create(self, request, *args, **kwargs):
bug_report_id = kwargs.get('bug_report_id')
try:
bug_report = await BugReport.objects.aget(id=bug_report_id, user=request.user)
except BugReport.DoesNotExist:
return create_standardized_error_response(
code=ResponseCode.NOT_FOUND,
message='Bug反馈不存在',
status_code=status.HTTP_404_NOT_FOUND
)
serializer = self.get_serializer(data=request.data)
is_valid = await sync_to_async(serializer.is_valid)()
if is_valid:
# 兜底:serializer.create 内部有同步 ORM(comment 及其图片/附件的 create)
comment = await sync_to_async(serializer.save)(
user=request.user,
bug_report=bug_report,
is_admin=False
)
comment_serializer = BugReportCommentSerializer(comment)
# 兜底:comment 序列化会触发 user 外键与 images/attachments 的同步懒加载
data = await sync_to_async(lambda: comment_serializer.data)()
return create_standardized_response(
code=ResponseCode.SUCCESS,
data=data,
message='回复成功',
status_code=status.HTTP_201_CREATED
)
return create_standardized_error_response(
code=ResponseCode.VALIDATION_ERROR,
data=serializer.errors,
message='回复失败',
status_code=status.HTTP_400_BAD_REQUEST
)