From c3ce76bc47283c206a4a087ae48a2833531f14bf Mon Sep 17 00:00:00 2001 From: yuetsh <517252939@qq.com> Date: Thu, 21 May 2026 18:46:40 -0600 Subject: [PATCH] fix --- problemset/management/__init__.py | 0 problemset/management/commands/__init__.py | 0 .../commands/fix_problemset_progress.py | 80 +++++++++++++++++++ 3 files changed, 80 insertions(+) create mode 100644 problemset/management/__init__.py create mode 100644 problemset/management/commands/__init__.py create mode 100644 problemset/management/commands/fix_problemset_progress.py diff --git a/problemset/management/__init__.py b/problemset/management/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/problemset/management/commands/__init__.py b/problemset/management/commands/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/problemset/management/commands/fix_problemset_progress.py b/problemset/management/commands/fix_problemset_progress.py new file mode 100644 index 0000000..a6d412c --- /dev/null +++ b/problemset/management/commands/fix_problemset_progress.py @@ -0,0 +1,80 @@ +from django.core.management.base import BaseCommand + +from problemset.models import ProblemSetProblem, ProblemSetProgress, ProblemSetSubmission +from submission.models import JudgeStatus, Submission + + +class Command(BaseCommand): + help = "根据实际提交记录修复题单进度数据" + + def add_arguments(self, parser): + parser.add_argument("--problemset-id", type=int, help="只修复指定题单(不传则修复全部)") + parser.add_argument("--dry-run", action="store_true", help="只检查,不写入数据库") + + def handle(self, *args, **options): + dry_run = options["dry_run"] + problemset_id = options.get("problemset_id") + + progresses = ProblemSetProgress.objects.select_related("user", "problemset") + if problemset_id: + progresses = progresses.filter(problemset_id=problemset_id) + + total = progresses.count() + self.stdout.write(f"共检查 {total} 条进度记录{'(dry-run 模式)' if dry_run else ''}") + + fixed_count = 0 + for progress in progresses: + problemset_problems = ProblemSetProblem.objects.filter( + problemset=progress.problemset + ).select_related("problem") + + updated = False + for psp in problemset_problems: + problem_id = str(psp.problem_id) + if problem_id in progress.progress_detail: + continue + + accepted = ( + Submission.objects.filter( + user_id=progress.user_id, + problem_id=psp.problem_id, + result=JudgeStatus.ACCEPTED, + ) + .order_by("create_time") + .first() + ) + if not accepted: + continue + + self.stdout.write( + f" 用户 {progress.user.username} | 题单「{progress.problemset.title}」" + f" | 题目 {psp.problem._id} 已AC但进度未记录" + ) + if dry_run: + continue + + progress.progress_detail[problem_id] = { + "score": psp.score, + "submit_time": accepted.create_time.isoformat(), + } + if not ProblemSetSubmission.objects.filter( + problemset=progress.problemset, + user=progress.user, + problem=psp.problem, + ).exists(): + ProblemSetSubmission.objects.create( + problemset=progress.problemset, + user=progress.user, + submission=accepted, + problem=psp.problem, + ) + updated = True + + if updated: + progress.update_progress() + fixed_count += 1 + + if dry_run: + self.stdout.write(self.style.WARNING("dry-run 完成,未写入任何数据")) + else: + self.stdout.write(self.style.SUCCESS(f"修复完成,共更新 {fixed_count} 条进度记录"))