From 36b3cd6b21b2ca0371ab0637b2776376cdd1d2b6 Mon Sep 17 00:00:00 2001 From: yuetsh <517252939@qq.com> Date: Mon, 26 Oct 2026 09:56:32 +0800 Subject: [PATCH] =?UTF-8?q?feat(=E7=BB=93=E6=9E=9C):=20=E5=88=A4=E5=AE=8C?= =?UTF-8?q?=E4=B9=8B=E5=90=8E=E6=B5=8B=E8=AF=95=E7=82=B9=E4=B8=80=E6=A0=BC?= =?UTF-8?q?=E4=B8=80=E6=A0=BC=E4=BA=AE=E8=B5=B7=E6=9D=A5=EF=BC=8C=E9=94=99?= =?UTF-8?q?=E7=9A=84=E9=82=A3=E6=A0=BC=E5=86=99=E7=9D=80=E7=AC=AC=E5=87=A0?= =?UTF-8?q?=E7=BB=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 借小丑牌结算时一张张牌亮起来:结果里每组测试点一个方块,从左往右依次亮, 对的绿、错的红并写组号,不到 1 秒亮完,提示和按钮亮完才出来,全对时亮完再放烟花。 大字和「通过几个」判完马上就有;只播刚交的那条,刷新、看旧提交、系统减少动画都直接全亮。 提交详情多给每组对没对(只有对错,不带数据),比赛照旧不给。 Co-Authored-By: Claude Opus 5.5 --- apps/api/src/routes/submission.ts | 8 +- .../src/oj/problem/components/CaseBlocks.vue | 112 +++++++ .../oj/problem/components/ResultHeader.vue | 22 +- .../problem/components/SubmissionEffects.vue | 32 +- .../problem/components/SubmissionResult.vue | 304 ++++++++++-------- apps/web/src/oj/problem/utils/caseReveal.ts | 15 + apps/web/src/oj/store/submission.ts | 21 ++ packages/contract/src/submission.ts | 5 + 8 files changed, 375 insertions(+), 144 deletions(-) create mode 100644 apps/web/src/oj/problem/components/CaseBlocks.vue create mode 100644 apps/web/src/oj/problem/utils/caseReveal.ts diff --git a/apps/api/src/routes/submission.ts b/apps/api/src/routes/submission.ts index c465391..d6625f1 100644 --- a/apps/api/src/routes/submission.ts +++ b/apps/api/src/routes/submission.ts @@ -372,8 +372,12 @@ function caseSummary(submission: typeof schema.submission.$inferSelect) { if (submission.contestId !== null || submission.language === "SQL") return null const data = asRecord(submission.info).data if (!Array.isArray(data) || data.length === 0) return null - const passed = data.filter((item) => asRecord(item).result === JudgeStatus.ACCEPTED).length - return { passed, total: data.length } + // 判题时已经按组号排过(judge/run.ts),这里再排一次:老数据不一定是排好的 + const results = data + .map((item) => asRecord(item)) + .sort((a, b) => Number(a.test_case) - Number(b.test_case)) + .map((item) => item.result === JudgeStatus.ACCEPTED) + return { passed: results.filter(Boolean).length, total: results.length, results } } /** 列表行的 caseSummary:SQL 里数好的两个数,为 null 的情形和详情一致(SQL 题、没有逐点结果) */ diff --git a/apps/web/src/oj/problem/components/CaseBlocks.vue b/apps/web/src/oj/problem/components/CaseBlocks.vue new file mode 100644 index 0000000..f8839fb --- /dev/null +++ b/apps/web/src/oj/problem/components/CaseBlocks.vue @@ -0,0 +1,112 @@ + + + + + diff --git a/apps/web/src/oj/problem/components/ResultHeader.vue b/apps/web/src/oj/problem/components/ResultHeader.vue index 8b8eabf..71cd3d0 100644 --- a/apps/web/src/oj/problem/components/ResultHeader.vue +++ b/apps/web/src/oj/problem/components/ResultHeader.vue @@ -1,5 +1,6 @@