Files
chunyu_project/user/views/activities.py
T
2026-08-05 23:59:15 +08:00

97 lines
4.0 KiB
Python

from django.db.models import Q
from rest_framework.views import APIView
from rest_framework.permissions import IsAuthenticated
from rest_framework import status
from drf_yasg.utils import swagger_auto_schema
from drf_yasg import openapi
from learn.models import ChapterRead
from article.models import Article
from learn.models import CourseFavorite
from utils.response_codes import create_standardized_response, create_standardized_error_response
success_response = openapi.Response('成功', examples={'application/json': {'code': 10000, 'message': 'success'}})
unauthorized_response = openapi.Response('未授权', examples={'application/json': {'code': 40101, 'message': '未登录'}})
class UserActivityView(APIView):
permission_classes = [IsAuthenticated]
@swagger_auto_schema(
tags=['用户'],
operation_summary='获取用户活动时间线',
operation_description='聚合用户的各种活动(发表文章、收藏、学习进度等),按时间倒序返回',
manual_parameters=[
openapi.Parameter('page', openapi.IN_QUERY, description='页码', type=openapi.TYPE_INTEGER, default=1),
openapi.Parameter('page_size', openapi.IN_QUERY, description='每页数量', type=openapi.TYPE_INTEGER, default=20),
],
responses={200: success_response, 401: unauthorized_response},
)
def get(self, request):
user = request.user
page = int(request.query_params.get('page', 1))
page_size = int(request.query_params.get('page_size', 20))
activities = []
# 文章活动
articles = Article.objects.filter(author=user, status='published').order_by('-created_at')[:50]
for article in articles:
activities.append({
'id': f'article_{article.id}',
'type': 'article',
'title': '发表文章',
'description': f'发布了《{article.title}》',
'target_id': article.id,
'target_type': 'article',
'created_at': article.created_at.strftime('%Y-%m-%d %H:%M:%S'),
'timestamp': int(article.created_at.timestamp()),
})
# 收藏活动
favorites = CourseFavorite.objects.filter(user=user).select_related('course').order_by('-created_at')[:50]
for fav in favorites:
activities.append({
'id': f'favorite_{fav.id}',
'type': 'favorite',
'title': '收藏课程',
'description': f'收藏了《{fav.course.title}》',
'target_id': fav.course.id,
'target_type': 'course',
'created_at': fav.created_at.strftime('%Y-%m-%d %H:%M:%S'),
'timestamp': int(fav.created_at.timestamp()),
})
# 学习进度
reads = ChapterRead.objects.filter(user=user, completed=True).select_related('chapter', 'course').order_by('-completed_at')[:50]
for read in reads:
activities.append({
'id': f'study_{read.id}',
'type': 'study',
'title': '完成学习',
'description': f'完成了《{read.course.title}》- {read.chapter.title}',
'target_id': read.chapter.id,
'target_type': 'chapter',
'created_at': read.completed_at.strftime('%Y-%m-%d %H:%M:%S') if read.completed_at else '',
'timestamp': int(read.completed_at.timestamp()) if read.completed_at else 0,
})
# 按时间戳倒序排序
activities.sort(key=lambda x: x['timestamp'], reverse=True)
# 分页
total = len(activities)
start = (page - 1) * page_size
end = start + page_size
paginated = activities[start:end]
return create_standardized_response(
data={
'activities': paginated,
'total': total,
'page': page,
'page_size': page_size,
'has_more': end < total,
}
)