from adrf.views import APIView from rest_framework.permissions import IsAuthenticated from rest_framework import status from utils.response_codes import ResponseCode, create_standardized_response, create_standardized_error_response from tool.models import Tool, ToolFavorite from article.models import Article, ArticleFavorite from learn.models import Course, CourseFavorite from apidirectory.models import ApiItem, ApiFavorite from drf_yasg.utils import swagger_auto_schema from drf_yasg import openapi from chunyu_project.common_schemas import success_response, error_response, unauthorized_response class MyFavoritesView(APIView): permission_classes = [IsAuthenticated] @swagger_auto_schema( tags=['收藏'], operation_summary='获取我的收藏', operation_description='获取当前用户的收藏列表,支持按类型筛选(tool/article/course/all)', manual_parameters=[ openapi.Parameter('type', openapi.IN_QUERY, description='收藏类型(all/tool/article/course),默认all', type=openapi.TYPE_STRING), ], responses={200: success_response, 401: unauthorized_response}, ) async def get(self, request): content_type = request.query_params.get('type', 'all') results = [] if content_type == 'all' or content_type == 'tool': tool_favs = ToolFavorite.objects.filter( user=request.user ).select_related('tool', 'tool__category').order_by('-created_at') async for tf in tool_favs: results.append({ 'id': tf.tool.id, 'type': 'tool', 'title': tf.tool.name, 'description': tf.tool.description, 'icon': tf.tool.icon, 'color': getattr(tf.tool, 'color', ''), 'url_path': tf.tool.url_path, 'category': getattr(tf.tool.category, 'name', '') if tf.tool.category else '', 'created_at': tf.created_at.strftime('%Y-%m-%d %H:%M:%S'), }) if content_type == 'all' or content_type == 'article': article_favs = ArticleFavorite.objects.filter( user=request.user ).select_related('article', 'article__author').order_by('-created_at') async for af in article_favs: results.append({ 'id': af.article.id, 'type': 'article', 'title': af.article.title, 'description': af.article.excerpt or '', 'category': af.article.category, 'tags': getattr(af.article, 'tags', []), 'author': getattr(af.article.author, 'nickname', '') if af.article.author else '', 'author_id': af.article.author_id, 'views': af.article.views, 'likes': af.article.likes, 'cover_image': '', 'created_at': af.created_at.strftime('%Y-%m-%d %H:%M:%S'), }) if content_type == 'all' or content_type == 'course': course_favs = CourseFavorite.objects.filter( user=request.user ).select_related('course', 'course__author').order_by('-created_at') async for cf in course_favs: results.append({ 'id': cf.course.id, 'type': 'course', 'title': cf.course.title, 'description': cf.course.description, 'category': cf.course.category, 'level': cf.course.level, 'icon_name': getattr(cf.course, 'icon_name', ''), 'color': getattr(cf.course, 'color', ''), 'chapters_count': await cf.course.chapters.acount() if hasattr(cf.course, 'chapters') else 0, 'author': getattr(cf.course.author, 'nickname', '') if cf.course.author else '', 'author_id': cf.course.author_id, 'created_at': cf.created_at.strftime('%Y-%m-%d %H:%M:%S'), }) if content_type == 'all' or content_type == 'api': api_favs = ApiFavorite.objects.filter( user=request.user ).select_related('api_item').order_by('-created_at') async for af in api_favs: results.append({ 'id': af.api_item.id, 'type': 'api', 'title': af.api_item.name, 'description': af.api_item.description or '', 'icon': 'ApiOutlined', 'color': af.api_item.color or '#faad14', 'url_path': af.api_item.url_path or '', 'category': getattr(af.api_item.category, 'name', '') if af.api_item.category else '', 'created_at': af.created_at.strftime('%Y-%m-%d %H:%M:%S'), }) counts = { 'total': len(results), 'tool': await ToolFavorite.objects.filter(user=request.user).acount(), 'article': await ArticleFavorite.objects.filter(user=request.user).acount(), 'course': await CourseFavorite.objects.filter(user=request.user).acount(), 'api': await ApiFavorite.objects.filter(user=request.user).acount(), } return create_standardized_response( data={'results': results, 'counts': counts}, code=ResponseCode.SUCCESS )