sync from local backup
This commit is contained in:
@@ -0,0 +1,96 @@
|
||||
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,
|
||||
}
|
||||
)
|
||||
Reference in New Issue
Block a user