This commit is contained in:
2026-05-21 18:46:40 -06:00
parent 1d08b29255
commit c3ce76bc47
3 changed files with 80 additions and 0 deletions

View File

View File

@@ -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} 条进度记录"))