diff --git a/apps/web/src/shared/components/CollabModal.vue b/apps/web/src/shared/components/CollabModal.vue index df2f5c0..2c47542 100644 --- a/apps/web/src/shared/components/CollabModal.vue +++ b/apps/web/src/shared/components/CollabModal.vue @@ -15,6 +15,11 @@ import { enhanceCompletion } from "shared/extensions/autocompletion" import { languageExtension } from "shared/extensions/language" import { useCollabDoc } from "../composables/collabDoc" import { useCollabStore } from "shared/store/collab" +import { MdPreview } from "md-editor-v3" +import "md-editor-v3/lib/preview.css" +import { getProblem } from "oj/api" +import type { Problem } from "utils/types" +import SQLDataTable from "oj/problem/components/SQLDataTable.vue" const isDark = useDark() const collabStore = useCollabStore() @@ -54,6 +59,51 @@ const extensions = computed(() => [ getInitialExtension(), ]) +/** + * 题面直接放在弹框左侧。原来只有一个「打开题面」链接,老师得在两个标签页之间 + * 来回切着对照学生的代码。 + * + * 不复用 ProblemContent:它读写全局的 problemStore,老师接单时可能正开着另一道题 + * 的详情页,一写就把那边的题面换掉了;它的「测试」按钮跑的也是 codeStore 里老师 + * 自己的代码。这里只要只读的题面。 + * + * 求助入口在比赛里是关掉的(Form.vue 的 showHelpButton),problemId 一定是公开 + * 题目的展示 ID,按非比赛的接口取就行。 + */ +const problem = ref(null) +const problemLoading = ref(false) + +watch( + () => collabStore.room?.problemId, + async (problemId) => { + if (!problemId) { + problem.value = null + problemLoading.value = false + return + } + if (problem.value?._id === problemId) return + problem.value = null + problemLoading.value = true + try { + const res = await getProblem(problemId, "") + // 请求在路上时老师结束协作、又接了另一道题的单,旧响应不能盖掉新题面 + if (collabStore.room?.problemId === problemId) problem.value = res + } catch { + // 取不到就留空,右上角的「打开题面」还能兜底 + } finally { + if (collabStore.room?.problemId === problemId) + problemLoading.value = false + } + }, + { immediate: true }, +) + +const sqlDisplay = computed(() => problem.value?.sqlDisplay ?? null) +const sqlExpectedQuery = computed(() => { + const exp = sqlDisplay.value?.expected + return exp && "columns" in exp ? exp : null +}) + const bind = (view: EditorView) => { if (!collabStore.isTeacher || !collabStore.room) return // ★ 教师端 seedContent 必须是 null —— 内容全部来自学生端 @@ -98,7 +148,7 @@ onUnmounted(() => { - - + + + + + +