92 lines
3.4 KiB
Python
92 lines
3.4 KiB
Python
from rest_framework.decorators import api_view, parser_classes, authentication_classes, permission_classes
|
||
from rest_framework.response import Response
|
||
from rest_framework import status
|
||
from rest_framework.parsers import MultiPartParser, FormParser
|
||
from rest_framework.permissions import IsAuthenticated
|
||
from django.views.decorators.csrf import csrf_exempt
|
||
from .oss import OSSUploader
|
||
from drf_yasg.utils import swagger_auto_schema
|
||
from drf_yasg import openapi
|
||
import logging
|
||
from userapp.authentication import RedisTokenAuthentication
|
||
|
||
logger = logging.getLogger(__name__)
|
||
|
||
@swagger_auto_schema(
|
||
method='post',
|
||
operation_description="通用文件上传接口,上传到OSS",
|
||
manual_parameters=[
|
||
openapi.Parameter(
|
||
'file',
|
||
openapi.IN_FORM,
|
||
description="需要上传的文件",
|
||
type=openapi.TYPE_FILE,
|
||
required=True
|
||
),
|
||
openapi.Parameter(
|
||
'is_permanent',
|
||
openapi.IN_FORM,
|
||
description="是否永久保存文件,默认为临时文件",
|
||
type=openapi.TYPE_BOOLEAN,
|
||
default=False
|
||
),
|
||
openapi.Parameter(
|
||
'filename',
|
||
openapi.IN_FORM,
|
||
description="自定义文件名(可选),如果不提供则自动生成",
|
||
type=openapi.TYPE_STRING,
|
||
required=False
|
||
),
|
||
],
|
||
responses={
|
||
200: openapi.Response(
|
||
description="上传成功",
|
||
schema=openapi.Schema(
|
||
type=openapi.TYPE_OBJECT,
|
||
properties={
|
||
'url': openapi.Schema(type=openapi.TYPE_STRING, description="文件访问URL"),
|
||
'key': openapi.Schema(type=openapi.TYPE_STRING, description="OSS对象键名"),
|
||
'is_permanent': openapi.Schema(type=openapi.TYPE_BOOLEAN, description="是否永久文件")
|
||
}
|
||
)
|
||
),
|
||
400: openapi.Response(description="请求错误或上传失败"),
|
||
401: openapi.Response(description="认证失败")
|
||
},
|
||
tags=['文件上传'],
|
||
security=[{'Bearer': []}]
|
||
)
|
||
@csrf_exempt
|
||
@api_view(['POST'])
|
||
@parser_classes([MultiPartParser, FormParser])
|
||
@authentication_classes([RedisTokenAuthentication])
|
||
@permission_classes([IsAuthenticated])
|
||
def upload_file(request):
|
||
"""
|
||
通用文件上传接口,将文件上传到OSS
|
||
文件保存在 upload/{temporary|permanent}/{date}/{filename} 结构下
|
||
需要提供有效的认证令牌
|
||
"""
|
||
try:
|
||
# 检查是否有文件
|
||
if 'file' not in request.FILES:
|
||
return Response({"error": "No file provided"}, status=status.HTTP_400_BAD_REQUEST)
|
||
|
||
file_obj = request.FILES['file']
|
||
|
||
# 获取参数
|
||
is_permanent = request.data.get('is_permanent', 'false').lower() == 'true'
|
||
filename = request.data.get('filename', None)
|
||
|
||
# 上传文件
|
||
uploader = OSSUploader()
|
||
result = uploader.upload_file(file_obj, is_permanent, filename)
|
||
|
||
return Response(result, status=status.HTTP_200_OK)
|
||
|
||
except Exception as e:
|
||
logger.error(f"File upload failed: {str(e)}")
|
||
return Response(
|
||
{"error": "File upload failed", "detail": str(e)},
|
||
status=status.HTTP_400_BAD_REQUEST
|
||
) |