feat(协作): 老师协作时右栏顶上一条协作条,结果页签先摆学生最近一次交的,抽屉变成「他的提交」

- 协作条:「正在帮 谁 · 语言 · 看他交过什么 ↗ · 结束协作」,从工具栏里挪出来,一眼看得出
  编辑器里是学生的代码。「看他交过什么」带上学生用户名、开新标签(原来只带题号,还得再筛一遍)
- 老师接单后「结果」页签原来是空的:现在摆学生在这道题上最近一次交的结果,可刷新;
  不给 AI 提示(那是按登录的人自己的失败次数解锁的)
- 抽屉「我的提交」在协作中变成「他的提交」,列的是学生的提交,只能复制、不能放回编辑器
  (放回去会经协作通道直接盖掉学生正在写的代码),也不显示老师自己的排名
- 学生排队求助中、或者老师正在帮他时换题:先确认一句。换题会断开协作 / 撤掉举手,
  原来一点「下一题」就把正在帮他的老师踢出去了
- 求助按钮文案:「举手求助」→「已举手 · 前面 2 人」→「某某 老师在帮你」
- 提交列表加 exactUsername=1:用户名精确匹配。原来只有「包含」,ks24a1 会把 ks24a10 的提交
  也捞进来

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
xuyueandClaude Opus 5.5 committed 2026-09-28 18:28:53 +08:00
1 parent 11368813cc
commit 0c2ff68e9b
13 files changed
+287 -45

No files matched your search

@@ -26,6 +26,11 @@ import { useDark } from "@vueuse/core"
const props = defineProps<{
submission?: Submission
/**
* 看的是别人的提交(协作中的老师看学生最近一次交的):不给 AI 提示 —— 那是按登录的人
* 自己的失败次数解锁的 —— 也不给「这节课的下一题」
*/
peer?: boolean
}>()
const isDark = useDark()
@@ -89,7 +94,8 @@ const sampleCheck = computed(() => {
*/
const ctx = useProblemPageContext()
const showLessonNext = computed(
() => props.submission?.result === SubmissionStatus.accepted && ctx.value.lessonNext,
() =>
!props.peer && props.submission?.result === SubmissionStatus.accepted && ctx.value.lessonNext,
)
const msg = computed(() => {
@@ -130,7 +136,7 @@ const partialCases = computed(() => submissionPartialCases(props.submission))
// system_error 也要排掉:那是判题机自己崩了,学生代码没毛病,让 AI 去分析
// 只会瞎编一通,后端的失败计数同样不认这个状态。
const showAIHint = computed(() => {
if (!props.submission) return false
if (!props.submission || props.peer) return false
// 比赛题不给提示,和「求助」按钮一致。用 problem.contestId 而不是路由参数:
// 带 contestId 的题目只可能从比赛入口进来(题库列表按 contest_id is null 过滤)。
if (problemStore.problem?.contestId != null) return false