""" 管理端批次导出视图 """ from datetime import datetime from rest_framework import viewsets from rest_framework.decorators import action from drf_spectacular.utils import extend_schema from utils.response import success, error from apps.admins.authentication import AdminJWTAuthentication from apps.admins.permissions import IsAdminUser from apps.devices.models import DeviceBatch from apps.devices.serializers import DeviceBatchSerializer def parse_export_date(date_str): """ 解析导出日期字符串,支持 YYYY-MM-DD 和 YYYY/MM/DD 两种格式。 Bug #46 fix: normalize '/' separators to '-' before parsing, instead of calling strptime directly on user input which fails for YYYY/MM/DD. """ # Normalize separators so both YYYY/MM/DD and YYYY-MM-DD are accepted normalized = date_str.replace('/', '-') try: return datetime.strptime(normalized, '%Y-%m-%d') except ValueError: raise ValueError( f'日期格式无效: {date_str},请使用 YYYY-MM-DD 或 YYYY/MM/DD 格式' ) @extend_schema(tags=['管理员-库存']) class AdminBatchExportViewSet(viewsets.ViewSet): """管理端批次导出视图集""" authentication_classes = [AdminJWTAuthentication] permission_classes = [IsAdminUser] @action(detail=False, methods=['get'], url_path='export') def export(self, request): """ 按日期范围导出批次列表 GET /api/admin/batch-export/export?start_date=2026-01-01&end_date=2026-12-31 """ start_str = request.query_params.get('start_date', '') end_str = request.query_params.get('end_date', '') queryset = DeviceBatch.objects.all().order_by('-created_at') if start_str: try: # Bug #46 fix: use parse_export_date which normalises the separator start_date = parse_export_date(start_str) except ValueError as exc: return error(message=str(exc)) queryset = queryset.filter(created_at__date__gte=start_date.date()) if end_str: try: end_date = parse_export_date(end_str) except ValueError as exc: return error(message=str(exc)) queryset = queryset.filter(created_at__date__lte=end_date.date()) serializer = DeviceBatchSerializer(queryset, many=True) return success(data={'items': serializer.data})