From ce2a4629dadabd07de7b62ddc6c69f614ed8f9d2 Mon Sep 17 00:00:00 2001 From: yuetsh <517252939@qq.com> Date: Fri, 3 Oct 2025 02:03:19 +0800 Subject: [PATCH] =?UTF-8?q?=E5=87=BA=E9=A2=98=E4=BA=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problem/urls/oj.py | 2 ++ problem/views/oj.py | 41 ++++++++++++++++++++++++++++++++++++++--- utils/constants.py | 1 + utils/shortcuts.py | 5 ----- 4 files changed, 41 insertions(+), 8 deletions(-) diff --git a/problem/urls/oj.py b/problem/urls/oj.py index 3f4ab83..5fd1460 100644 --- a/problem/urls/oj.py +++ b/problem/urls/oj.py @@ -6,12 +6,14 @@ from ..views.oj import ( ProblemAPI, ContestProblemAPI, PickOneAPI, + ProblemAuthorAPI, ) urlpatterns = [ path("problem/tags", ProblemTagAPI.as_view()), path("problem", ProblemAPI.as_view()), path("problem/beat_count", ProblemSolvedPeopleCount.as_view()), + path("problem/author", ProblemAuthorAPI.as_view()), path("pickone", PickOneAPI.as_view()), path("contest/problem", ContestProblemAPI.as_view()), ] diff --git a/problem/views/oj.py b/problem/views/oj.py index a798df9..68d0fdd 100644 --- a/problem/views/oj.py +++ b/problem/views/oj.py @@ -1,10 +1,12 @@ from datetime import datetime import random from django.db.models import Q, Count +from django.core.cache import cache from account.models import User from submission.models import Submission, JudgeStatus from utils.api import APIView from account.decorators import check_contest_permission +from utils.constants import CacheKey from ..models import ProblemTag, Problem, ProblemRuleType from ..serializers import ( ProblemSerializer, @@ -82,6 +84,11 @@ class ProblemAPI(APIView): .filter(contest_id__isnull=True, visible=True) .order_by("-create_time") ) + + author = request.GET.get("author") + if author: + problems = problems.filter(created_by__username=author) + # 按照标签筛选 tag_text = request.GET.get("tag") if tag_text: @@ -98,6 +105,7 @@ class ProblemAPI(APIView): difficulty = request.GET.get("difficulty") if difficulty: problems = problems.filter(difficulty=difficulty) + # 根据profile 为做过的题目添加标记 data = self.paginate_data(request, problems, ProblemListSerializer) self._add_problem_status(request, data) @@ -166,17 +174,44 @@ class ProblemSolvedPeopleCount(APIView): if submission_count == 0: return self.success(rate) today = datetime.today() - twoYearAge = datetime(today.year - 2, today.month, today.day, 0, 0) + years_ago = datetime(today.year - 2, today.month, today.day, 0, 0) total_count = User.objects.filter( - is_disabled=False, last_login__gte=twoYearAge + is_disabled=False, last_login__gte=years_ago ).count() accepted_count = Submission.objects.filter( problem_id=problem_id, result=JudgeStatus.ACCEPTED, - create_time__gte=twoYearAge, + create_time__gte=years_ago, ).aggregate(user_count=Count("user_id", distinct=True))["user_count"] if accepted_count < total_count: rate = "%.2f" % ((total_count - accepted_count) / total_count * 100) else: rate = "0" return self.success(rate) + + +class ProblemAuthorAPI(APIView): + def get(self, request): + # 统计出题用户 + cached_data = cache.get(CacheKey.problem_authors) + if cached_data: + return self.success(cached_data) + + authors = ( + Problem.objects.filter( + visible=True, contest_id__isnull=True, created_by__is_disabled=False + ) + .values("created_by__username") + .annotate(problem_count=Count("id")) + .order_by("-problem_count") + ) + result = [ + { + "username": author["created_by__username"], + "problem_count": author["problem_count"], + } + for author in authors + ] + + cache.set(CacheKey.problem_authors, result, 3600) + return self.success(result) diff --git a/utils/constants.py b/utils/constants.py index 749b20d..ea5643f 100644 --- a/utils/constants.py +++ b/utils/constants.py @@ -25,6 +25,7 @@ class CacheKey: waiting_queue = "waiting_queue" contest_rank_cache = "contest_rank_cache" website_config = "website_config" + problem_authors = "problem_authors" class Difficulty(Choices): diff --git a/utils/shortcuts.py b/utils/shortcuts.py index 84e14fd..e21e406 100644 --- a/utils/shortcuts.py +++ b/utils/shortcuts.py @@ -57,11 +57,6 @@ def datetime2str(value, format="iso-8601"): return value return value.strftime(format) - -def timestamp2utcstr(value): - return datetime.datetime.utcfromtimestamp(value).isoformat() - - def natural_sort_key(s, _nsre=re.compile(r"(\d+)")): return [int(text) if text.isdigit() else text.lower() for text in re.split(_nsre, s)]