from adrf.views import APIView from rest_framework.response import Response from rest_framework import status from rest_framework.permissions import AllowAny, IsAuthenticated from django.http import JsonResponse from django.db.models import Count from drf_yasg.utils import swagger_auto_schema from drf_yasg import openapi from .models import ApiCategory, ApiItem, ApiFavorite from .serializers import ApiCategorySerializer, ApiItemSerializer class CategoryListView(APIView): permission_classes = [AllowAny] @swagger_auto_schema( operation_summary='获取API分类列表', operation_description='获取所有API分类及其关联的API数量', tags=['API接口大全'], responses={200: '成功'} ) async def get(self, request): categories = [c async for c in ApiCategory.objects.prefetch_related('items').all()] serializer = ApiCategorySerializer(categories, many=True) return JsonResponse({ 'code': 200, 'message': 'success', 'data': await serializer.adata }) class ApiItemListView(APIView): permission_classes = [AllowAny] @swagger_auto_schema( operation_summary='获取API列表', operation_description='获取API列表,支持分类筛选、搜索、排序', tags=['API接口大全'], manual_parameters=[ openapi.Parameter('category_id', openapi.IN_QUERY, description='分类ID', type=openapi.TYPE_INTEGER), openapi.Parameter('search', openapi.IN_QUERY, description='搜索关键词', type=openapi.TYPE_STRING), openapi.Parameter('ordering', openapi.IN_QUERY, description='排序字段', type=openapi.TYPE_STRING), ], responses={200: '成功'} ) async def get(self, request): category_id = request.query_params.get('category_id') search = request.query_params.get('search', '') ordering = request.query_params.get('ordering', '') items = ApiItem.objects.select_related('category').annotate( annotated_favorites_count=Count('favorites') ).filter(is_enabled=True) if category_id: items = items.filter(category_id=category_id) if search: items = items.filter(name__icontains=search) | items.filter(description__icontains=search) if ordering: if ordering == '-favorites_count': items = items.order_by('-annotated_favorites_count') elif ordering == 'favorites_count': items = items.order_by('annotated_favorites_count') else: items = items.order_by(ordering) else: items = items.order_by('sort_order', '-created_at') item_list = [x async for x in items] serializer = ApiItemSerializer(item_list, many=True, context={'request': request}) return JsonResponse({ 'code': 200, 'message': 'success', 'data': await serializer.adata }) class ApiItemDetailView(APIView): permission_classes = [AllowAny] @swagger_auto_schema( operation_summary='获取API详情', operation_description='获取单个API的详细信息', tags=['API接口大全'], responses={200: '成功'} ) async def get(self, request, pk): try: item = await ApiItem.objects.select_related('category').aget(pk=pk, is_enabled=True) serializer = ApiItemSerializer(item, context={'request': request}) return JsonResponse({ 'code': 200, 'message': 'success', 'data': await serializer.adata }) except ApiItem.DoesNotExist: return JsonResponse({ 'code': 404, 'message': 'API不存在', 'data': None }, status=status.HTTP_404_NOT_FOUND) class FavoriteToggleView(APIView): permission_classes = [IsAuthenticated] @swagger_auto_schema( operation_summary='切换API收藏状态', operation_description='收藏或取消收藏API接口', tags=['API接口大全'], responses={200: '成功'} ) async def post(self, request, pk): try: api_item = await ApiItem.objects.aget(pk=pk, is_enabled=True) except ApiItem.DoesNotExist: return JsonResponse({ 'code': 404, 'message': 'API不存在', 'data': None }, status=status.HTTP_404_NOT_FOUND) fav, created = await ApiFavorite.objects.aget_or_create(user=request.user, api_item=api_item) if not created: await fav.adelete() is_favorited = False else: is_favorited = True favorites_count = await ApiFavorite.objects.filter(api_item=api_item).acount() return JsonResponse({ 'code': 200, 'message': 'success', 'data': { 'id': api_item.id, 'is_favorited': is_favorited, 'favorites_count': favorites_count } }) def api_directory_index(request): return JsonResponse({ 'code': 200, 'message': 'API Directory index', 'data': { 'endpoints': { 'categories': '/api/apidirectory/categories/', 'items': '/api/apidirectory/items/', 'item_detail': '/api/apidirectory/items/{id}/', 'favorite_toggle': '/api/apidirectory/items/{id}/favorite/', } } })