170 lines
7.1 KiB
Python
170 lines
7.1 KiB
Python
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 serializer.adata
|
||
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 = serializer.is_valid()
|
||
if is_valid:
|
||
# 兜底:serializer.create 内部有同步 ORM(BugReport/BugReportImage/BugReportAttachment 的 create)
|
||
bug_report = await serializer.asave(user=request.user)
|
||
detail_serializer = BugReportDetailSerializer(bug_report)
|
||
# 兜底:detail 序列化会触发 user/images/attachments/comments 的同步懒加载
|
||
data = await detail_serializer.adata
|
||
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 serializer.adata
|
||
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 = 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 comment_serializer.adata
|
||
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
|
||
)
|