feat(提交结果): 没通过时显示「通过 x/y 个测试点」;编译失败不等三次就能用 AI 分析
Some checks failed
Deploy / deploy (push) Has been cancelled

学生拿不到 info(每个点带 output_md5,只给管理员),测试点表格从来只有管理员看得见,
学生这边只有一句「答案错误」—— 从 2/8 交到 6/8 的人,感受是连输五次。

- 提交详情新增 caseSummary,后端从 info 数出通过数下发,不放开原文。
  比赛提交、SQL 题(被杀的测试点会 break,total 偏小)、无逐点结果时为 null
- 结果面板标题缀上通过数并加进度条,提交详情页标题同步;一个都没过时不缀
- POST /ai/hint 对编译失败跳过失败次数门槛,throttleAi 照旧;前端显示条件同口径

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013TecwAowmYcoNZRheSyTgH
This commit is contained in:
2026-09-13 07:25:00 -06:00
parent a833819679
commit 9132901cc7
7 changed files with 85 additions and 9 deletions

View File

@@ -7,6 +7,8 @@ import { JUDGE_STATUS, SubmissionStatus } from "utils/constants"
import {
submissionCaseResults,
submissionMemoryFormat,
submissionPartialCases,
submissionResultTitle,
submissionTimeFormat,
} from "utils/functions"
import type { Submission } from "utils/types"
@@ -57,8 +59,13 @@ const msg = computed(() => {
return msg
})
// 部分测试点通过时的进度。学生拿不到 info那张测试点表格只有管理员看得见
// 这是学生这边唯一能看出「比上次多过了几个点」的地方。
const partialCases = computed(() => submissionPartialCases(props.submission))
// 是否显示AI提示区域。
// 阈值和后端 POST /ai/hint 共用契约里的 HINT_MIN_FAILURES别在这里写死数字
// 编译失败不数次数,和后端同口径(理由见 HINT_MIN_FAILURES 的注释);
// failCount 现在含服务端下发的历史失败数,刷新页面不会把进度清掉。
// system_error 也要排掉:那是判题机自己崩了,学生代码没毛病,让 AI 去分析
// 只会瞎编一通,后端的失败计数同样不认这个状态。
@@ -68,7 +75,8 @@ const showAIHint = computed(() => {
// 带 contestId 的题目只可能从比赛入口进来(题库列表按 contest_id is null 过滤)。
if (problemStore.problem?.contestId != null) return false
return (
problemStore.failCount >= HINT_MIN_FAILURES &&
(problemStore.failCount >= HINT_MIN_FAILURES ||
props.submission.result === SubmissionStatus.compile_error) &&
props.submission.result !== SubmissionStatus.accepted &&
props.submission.result !== SubmissionStatus.ast_check_failed &&
props.submission.result !== SubmissionStatus.system_error &&
@@ -172,9 +180,18 @@ const columns: DataTableColumn<JudgeCaseResult>[] = [
<div v-if="submission">
<n-alert
:type="JUDGE_STATUS[submission.result]['type']"
:title="JUDGE_STATUS[submission.result]['title']"
:title="submissionResultTitle(submission)"
class="mb-3"
/>
>
<template v-if="partialCases" #default>
<n-progress
type="line"
status="success"
:percentage="(partialCases.passed / partialCases.total) * 100"
:show-indicator="false"
/>
</template>
</n-alert>
<n-flex
vertical
v-if="

View File

@@ -10,6 +10,7 @@ import {
parseTime,
submissionCaseResults,
submissionMemoryFormat,
submissionResultTitle,
submissionTimeFormat,
utoa,
} from "utils/functions"
@@ -129,7 +130,7 @@ onMounted(init)
<n-alert
style="flex: 1"
:type="JUDGE_STATUS[submission.result]['type']"
:title="JUDGE_STATUS[submission.result]['title']"
:title="submissionResultTitle(submission)"
>
<n-flex>
<span>提交时间{{ parseTime(submission.createTime) }}</span>