117 lines
5.5 KiB
Python
117 lines
5.5 KiB
Python
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
|
||
)
|