71 lines
2.2 KiB
Python
71 lines
2.2 KiB
Python
import os
|
|
import uuid
|
|
from pathlib import Path
|
|
|
|
from django.conf import settings
|
|
from django.views.static import serve as static_serve
|
|
from rest_framework.decorators import api_view, permission_classes, parser_classes
|
|
from rest_framework.permissions import IsAuthenticated
|
|
from rest_framework.parsers import MultiPartParser
|
|
from rest_framework.response import Response
|
|
from rest_framework import status
|
|
|
|
|
|
H5_DIST_ROOT = Path(settings.BASE_DIR) / 'dist' / 'h5'
|
|
|
|
|
|
def serve_h5(request, path=''):
|
|
"""
|
|
H5 SPA 静态资源 + history 路由回退。
|
|
- /m/ 或 /m/<route>(无扩展名/不存在的路径)→ 返回 dist/index.html
|
|
- /m/assets/xxx.js, /m/img/xxx.jpg 等真实存在的文件 → 直出
|
|
"""
|
|
if path:
|
|
candidate = H5_DIST_ROOT / path
|
|
if candidate.is_file():
|
|
return static_serve(request, path, document_root=str(H5_DIST_ROOT))
|
|
return static_serve(request, 'index.html', document_root=str(H5_DIST_ROOT))
|
|
|
|
|
|
ALLOWED_IMAGE_TYPES = {
|
|
'image/jpeg', 'image/png', 'image/gif', 'image/webp', 'image/bmp',
|
|
}
|
|
|
|
MAX_FILE_SIZE = 10 * 1024 * 1024 # 10MB
|
|
|
|
|
|
@api_view(['POST'])
|
|
@permission_classes([IsAuthenticated])
|
|
@parser_classes([MultiPartParser])
|
|
def upload_image(request):
|
|
file = request.FILES.get('file')
|
|
if not file:
|
|
return Response({'detail': '未提供文件'}, status=status.HTTP_400_BAD_REQUEST)
|
|
|
|
if file.content_type not in ALLOWED_IMAGE_TYPES:
|
|
return Response(
|
|
{'detail': '仅支持 JPG/PNG/GIF/WEBP/BMP 格式的图片'},
|
|
status=status.HTTP_400_BAD_REQUEST,
|
|
)
|
|
|
|
if file.size > MAX_FILE_SIZE:
|
|
return Response(
|
|
{'detail': '文件大小不能超过 10MB'},
|
|
status=status.HTTP_400_BAD_REQUEST,
|
|
)
|
|
|
|
ext = os.path.splitext(file.name)[1].lower()
|
|
filename = f"{uuid.uuid4().hex}{ext}"
|
|
relative_path = f"uploads/{filename}"
|
|
|
|
full_path = os.path.join(settings.MEDIA_ROOT, relative_path)
|
|
os.makedirs(os.path.dirname(full_path), exist_ok=True)
|
|
|
|
with open(full_path, 'wb+') as dest:
|
|
for chunk in file.chunks():
|
|
dest.write(chunk)
|
|
|
|
url = request.build_absolute_uri(f"/{settings.MEDIA_URL}{relative_path}")
|
|
|
|
return Response({'url': url, 'path': relative_path})
|