Files
game-cards-poker-design/backend/apps/exports/views.py
Poker Design Developer 48629736f4 Implement Django backend and Vue frontend structure
- Django backend with projects, templates, exports apps
- SQLite database models for Project, Asset, CardLayer
- REST API endpoints for project management
- Vue frontend with Vite, Element Plus, Fabric.js
- Home page for project selection
- Editor page with Fabric.js canvas integration
2026-05-31 14:55:01 +08:00

97 lines
3.1 KiB
Python

from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework import status
from django.http import HttpResponse
from ..projects.models import Project
from .utils import generate_card_png
import zipfile
import io
import os
@api_view(['POST'])
def export_project(request, pk):
"""
批量导出整副牌为ZIP文件
请求体: { "resolution": "standard", "cards": "all" }
"""
try:
project = Project.objects.get(pk=pk)
except Project.DoesNotExist:
return Response({'error': 'Project not found'}, status=status.HTTP_404_NOT_FOUND)
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')
else:
cards = cards_filter if isinstance(cards_filter, list) else [cards_filter]
# 创建ZIP文件
zip_buffer = io.BytesIO()
with zipfile.ZipFile(zip_buffer, 'w', zipfile.ZIP_DEFLATED) as zip_file:
for card_key in cards:
try:
png = generate_card_png(project, card_key, resolution)
img_buffer = io.BytesIO()
png.save(img_buffer, format='PNG')
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)}")
continue
zip_buffer.seek(0)
# 保存到media目录
export_dir = os.path.join('media', '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())
return Response({
'download_url': f'/media/export/{project.id}/cards.zip',
'card_count': len(cards)
})
@api_view(['GET'])
def export_single_card(request, pk, card_key):
"""
导出单张牌PNG
"""
try:
project = Project.objects.get(pk=pk)
except Project.DoesNotExist:
return Response({'error': 'Project not found'}, status=status.HTTP_404_NOT_FOUND)
resolution = request.query_params.get('resolution', 'standard')
try:
png = generate_card_png(project, card_key, resolution)
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)