183 lines
6.9 KiB
Python
Executable File
183 lines
6.9 KiB
Python
Executable File
from rest_framework import viewsets
|
|
from rest_framework.decorators import action
|
|
from rest_framework.response import Response
|
|
from rest_framework import permissions
|
|
from django.utils import timezone
|
|
from .models import DiaryEntry, DailyProgress, Experience, Task, Comment
|
|
from .serializers import (
|
|
DiaryEntrySerializer, DailyProgressSerializer, ExperienceSerializer,
|
|
TaskSerializer, CommentSerializer
|
|
)
|
|
|
|
class DiaryEntryViewSet(viewsets.ModelViewSet):
|
|
serializer_class = DiaryEntrySerializer
|
|
permission_classes = [permissions.IsAuthenticated]
|
|
|
|
def get_queryset(self):
|
|
return DiaryEntry.objects.filter(user=self.request.user)
|
|
|
|
@action(detail=False, methods=['get'])
|
|
def today(self, request):
|
|
"""获取今天的日记"""
|
|
today = timezone.now().date()
|
|
entry, created = DiaryEntry.objects.get_or_create(user=request.user, date=today)
|
|
serializer = self.get_serializer(entry)
|
|
return Response(serializer.data)
|
|
|
|
@action(detail=False, methods=['get'])
|
|
def recent(self, request):
|
|
"""获取最近 7 天的日记"""
|
|
entries = DiaryEntry.objects.filter(user=request.user).order_by('-date')[:7]
|
|
serializer = self.get_serializer(entries, many=True)
|
|
return Response(serializer.data)
|
|
|
|
@action(detail=False, methods=['get'])
|
|
def stats(self, request):
|
|
"""获取统计信息"""
|
|
total_entries = DiaryEntry.objects.count()
|
|
total_tasks = Task.objects.count()
|
|
total_experiences = Experience.objects.count()
|
|
return Response({
|
|
'total_entries': total_entries,
|
|
'first_entry': DiaryEntry.objects.order_by('date').first().date if total_entries > 0 else None,
|
|
'latest_entry': DiaryEntry.objects.order_by('-date').first().date if total_entries > 0 else None,
|
|
'total_tasks': total_tasks,
|
|
'total_experiences': total_experiences,
|
|
})
|
|
|
|
@action(detail=True, methods=['post'])
|
|
def link_task(self, request, pk=None):
|
|
"""关联任务到日记"""
|
|
entry = self.get_object()
|
|
task_id = request.data.get('task_id')
|
|
progress_percent = request.data.get('progress_percent')
|
|
notes = request.data.get('notes', '')
|
|
|
|
task = Task.objects.get(id=task_id)
|
|
entry.link_task(task, progress_percent, notes)
|
|
|
|
return Response(DiaryEntrySerializer(entry).data)
|
|
|
|
@action(detail=True, methods=['post'])
|
|
def extract_experience(self, request, pk=None):
|
|
"""从日记提炼经验"""
|
|
entry = self.get_object()
|
|
exp = entry.extract_experience(
|
|
title=request.data.get('title'),
|
|
category=request.data.get('category'),
|
|
problem=request.data.get('problem'),
|
|
solution=request.data.get('solution'),
|
|
lesson_learned=request.data.get('lesson_learned', '')
|
|
)
|
|
return Response(ExperienceSerializer(exp).data)
|
|
|
|
class DailyProgressViewSet(viewsets.ModelViewSet):
|
|
queryset = DailyProgress.objects.all()
|
|
serializer_class = DailyProgressSerializer
|
|
|
|
|
|
class ExperienceViewSet(viewsets.ModelViewSet):
|
|
serializer_class = ExperienceSerializer
|
|
permission_classes = [permissions.IsAuthenticated]
|
|
|
|
def get_queryset(self):
|
|
return Experience.objects.filter(user=self.request.user)
|
|
|
|
@action(detail=False, methods=['get'])
|
|
def by_category(self, request):
|
|
"""按类别分组获取经验"""
|
|
categories = {}
|
|
for exp in Experience.objects.all():
|
|
cat = exp.get_category_display()
|
|
if cat not in categories:
|
|
categories[cat] = []
|
|
categories[cat].append(ExperienceSerializer(exp).data)
|
|
return Response(categories)
|
|
|
|
@action(detail=False, methods=['get'])
|
|
def recent(self, request):
|
|
"""获取最近 10 条经验"""
|
|
experiences = Experience.objects.order_by('-date', '-created_at')[:10]
|
|
serializer = self.get_serializer(experiences, many=True)
|
|
return Response(serializer.data)
|
|
|
|
|
|
class TaskViewSet(viewsets.ModelViewSet):
|
|
serializer_class = TaskSerializer
|
|
permission_classes = [permissions.IsAuthenticated]
|
|
|
|
def get_queryset(self):
|
|
return Task.objects.filter(user=self.request.user)
|
|
|
|
@action(detail=False, methods=['get'])
|
|
def by_status(self, request):
|
|
"""按状态分组获取任务"""
|
|
statuses = {}
|
|
for task in Task.objects.all():
|
|
status = task.get_status_display()
|
|
if status not in statuses:
|
|
statuses[status] = []
|
|
statuses[status].append(TaskSerializer(task).data)
|
|
return Response(statuses)
|
|
|
|
@action(detail=False, methods=['get'])
|
|
def active(self, request):
|
|
"""获取活跃任务(未完成和未取消)"""
|
|
tasks = Task.objects.exclude(status__in=['completed', 'cancelled'])
|
|
serializer = self.get_serializer(tasks, many=True)
|
|
return Response(serializer.data)
|
|
|
|
@action(detail=False, methods=['get'])
|
|
def stats(self, request):
|
|
"""获取任务统计"""
|
|
total = Task.objects.count()
|
|
completed = Task.objects.filter(status='completed').count()
|
|
in_progress = Task.objects.filter(status='in_progress').count()
|
|
pending = Task.objects.filter(status='pending').count()
|
|
blocked = Task.objects.filter(status='blocked').count()
|
|
return Response({
|
|
'total': total,
|
|
'completed': completed,
|
|
'in_progress': in_progress,
|
|
'pending': pending,
|
|
'blocked': blocked,
|
|
'completion_rate': round(completed / total * 100, 1) if total > 0 else 0
|
|
})
|
|
|
|
@action(detail=True, methods=['post'])
|
|
def update_progress(self, request, pk=None):
|
|
"""更新任务进展"""
|
|
task = self.get_object()
|
|
percent = request.data.get('percent', task.progress_percent)
|
|
notes = request.data.get('notes', '')
|
|
task.update_progress(int(percent), notes)
|
|
return Response(TaskSerializer(task).data)
|
|
|
|
@action(detail=True, methods=['post'])
|
|
def complete(self, request, pk=None):
|
|
"""标记任务为完成"""
|
|
task = self.get_object()
|
|
task.mark_completed()
|
|
return Response(TaskSerializer(task).data)
|
|
|
|
|
|
class CommentViewSet(viewsets.ModelViewSet):
|
|
queryset = Comment.objects.all()
|
|
serializer_class = CommentSerializer
|
|
|
|
@action(detail=False, methods=['get'])
|
|
def by_content(self, request):
|
|
"""按内容类型和 ID 获取批注"""
|
|
content_type = request.query_params.get('content_type')
|
|
object_id = request.query_params.get('object_id')
|
|
|
|
if content_type and object_id:
|
|
comments = Comment.objects.filter(
|
|
content_type=content_type,
|
|
object_id=object_id
|
|
)
|
|
serializer = self.get_serializer(comments, many=True)
|
|
return Response(serializer.data)
|
|
|
|
return Response([])
|