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)