重构扑克牌设计系统:修复后端渲染bug,重写前端编辑器
This commit is contained in:
@@ -2,6 +2,7 @@ from rest_framework.decorators import api_view
|
||||
from rest_framework.response import Response
|
||||
from rest_framework import status
|
||||
from django.http import HttpResponse
|
||||
from django.conf import settings
|
||||
from ..projects.models import Project
|
||||
from .utils import generate_card_png
|
||||
import zipfile
|
||||
@@ -9,12 +10,22 @@ import io
|
||||
import os
|
||||
|
||||
|
||||
def _all_card_keys(project):
|
||||
"""生成所有 54 张牌的 key 列表"""
|
||||
keys = []
|
||||
for suit in ['spade', 'heart', 'club', 'diamond']:
|
||||
for rank in ['A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K']:
|
||||
keys.append(f"{suit}-{rank}")
|
||||
keys.append('joker-big')
|
||||
keys.append('joker-small')
|
||||
if project.export_include_back:
|
||||
keys.append('back')
|
||||
return keys
|
||||
|
||||
|
||||
@api_view(['POST'])
|
||||
def export_project(request, pk):
|
||||
"""
|
||||
批量导出整副牌为ZIP文件
|
||||
请求体: { "resolution": "standard", "cards": "all" }
|
||||
"""
|
||||
"""批量导出整副牌为 ZIP"""
|
||||
try:
|
||||
project = Project.objects.get(pk=pk)
|
||||
except Project.DoesNotExist:
|
||||
@@ -23,24 +34,13 @@ def export_project(request, pk):
|
||||
resolution = request.data.get('resolution', 'standard')
|
||||
cards_filter = request.data.get('cards', 'all')
|
||||
|
||||
# 确定要导出的牌
|
||||
cards = []
|
||||
if cards_filter == 'all':
|
||||
# 生成所有54张牌
|
||||
for suit in ['spade', 'heart', 'club', 'diamond']:
|
||||
for rank in ['A', '2', '3', '4', '5', '6', '7', '8', '9', '10']:
|
||||
cards.append(f"{suit}-{rank}")
|
||||
for face in ['J', 'Q', 'K']:
|
||||
cards.append(f"{suit}-{face}")
|
||||
cards.extend(['joker-big', 'joker-small'])
|
||||
|
||||
if project.export_include_back:
|
||||
cards.append('back')
|
||||
cards = _all_card_keys(project)
|
||||
else:
|
||||
cards = cards_filter if isinstance(cards_filter, list) else [cards_filter]
|
||||
|
||||
# 创建ZIP文件
|
||||
zip_buffer = io.BytesIO()
|
||||
failed = []
|
||||
with zipfile.ZipFile(zip_buffer, 'w', zipfile.ZIP_DEFLATED) as zip_file:
|
||||
for card_key in cards:
|
||||
try:
|
||||
@@ -50,31 +50,28 @@ def export_project(request, pk):
|
||||
img_buffer.seek(0)
|
||||
zip_file.writestr(f"{card_key}.png", img_buffer.getvalue())
|
||||
except Exception as e:
|
||||
# 记录错误但继续处理其他牌
|
||||
print(f"Error generating {card_key}: {str(e)}")
|
||||
failed.append({'card': card_key, 'error': str(e)})
|
||||
continue
|
||||
|
||||
zip_buffer.seek(0)
|
||||
|
||||
# 保存到media目录
|
||||
export_dir = os.path.join('media', 'export', str(project.id))
|
||||
export_dir = os.path.join(settings.MEDIA_ROOT, 'export', str(project.id))
|
||||
os.makedirs(export_dir, exist_ok=True)
|
||||
zip_path = os.path.join(export_dir, 'cards.zip')
|
||||
|
||||
with open(zip_path, 'wb') as f:
|
||||
f.write(zip_buffer.getvalue())
|
||||
|
||||
download_url = f"{settings.MEDIA_URL}export/{project.id}/cards.zip"
|
||||
return Response({
|
||||
'download_url': f'/media/export/{project.id}/cards.zip',
|
||||
'card_count': len(cards)
|
||||
'download_url': download_url,
|
||||
'card_count': len(cards),
|
||||
'failed': failed,
|
||||
})
|
||||
|
||||
|
||||
@api_view(['GET'])
|
||||
def export_single_card(request, pk, card_key):
|
||||
"""
|
||||
导出单张牌PNG
|
||||
"""
|
||||
"""导出单张牌 PNG"""
|
||||
try:
|
||||
project = Project.objects.get(pk=pk)
|
||||
except Project.DoesNotExist:
|
||||
@@ -87,10 +84,8 @@ def export_single_card(request, pk, card_key):
|
||||
img_buffer = io.BytesIO()
|
||||
png.save(img_buffer, format='PNG')
|
||||
img_buffer.seek(0)
|
||||
|
||||
response = HttpResponse(img_buffer, content_type='image/png')
|
||||
response['Content-Disposition'] = f'attachment; filename="{card_key}.png"'
|
||||
return response
|
||||
|
||||
except Exception as e:
|
||||
return Response({'error': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
|
||||
|
||||
Reference in New Issue
Block a user