From 1b149a4f3f0f653ea23a02fc2c558f035906fd23 Mon Sep 17 00:00:00 2001 From: yuetsh <517252939@qq.com> Date: Mon, 28 Sep 2026 09:15:50 +0800 Subject: [PATCH] =?UTF-8?q?fix(=E9=A2=98=E7=9B=AE):=20=E5=9C=A8=E9=A2=98?= =?UTF-8?q?=E7=9B=AE=E9=A1=B5=E9=87=8C=E7=9B=B4=E6=8E=A5=E6=8D=A2=E9=A2=98?= =?UTF-8?q?=EF=BC=88=E4=B8=8B=E4=B8=80=E9=A2=98=E3=80=81=E9=A2=98=E5=8F=B7?= =?UTF-8?q?=E7=9B=B4=E8=BE=BE=EF=BC=89=E5=90=8E=EF=BC=8C=E4=BE=8B=E5=AD=90?= =?UTF-8?q?=E5=92=8C=E8=AF=AD=E8=A8=80=E8=BF=98=E5=81=9C=E5=9C=A8=E4=B8=8A?= =?UTF-8?q?=E4=B8=80=E9=81=93=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 题目页换题是同一个组件复用、只换路由参数,几处只在创建时读一次的状态就停在了上一道题: - 例子:新题下面摆着旧题的例子,「测试」也拿旧例子比对 - 语言:下拉选项不跟着变,也不回退——从 Python 题跳到 SQL 题,语言停在 Python,提交必被拒 - 比赛 / 题单的编辑器只在挂载时载入一次代码 - 流程图:分数按钮、评分弹框、「我的流程图」还是上一道题的,上一道题还没评完的那次会挂到新题上 语言回退挪进 problem store 的 supportedLanguage(),两个编辑器在载入草稿之前调用, 保证先定语言再读这门语言的草稿。没有用给整块加 key 强制重新挂载的办法:课堂协作的 绑定依赖组件复用,重挂载会让协作中切题的老师语言恢复不了。 Co-Authored-By: Claude Opus 5.5 --- .../src/oj/problem/components/BasicEditor.vue | 10 +++- .../oj/problem/components/EditorToolbar.vue | 32 +++++------ .../oj/problem/components/ProblemContent.vue | 21 ++++++- .../oj/problem/components/ProblemEditor.vue | 1 + .../oj/problem/components/SubmitFlowchart.vue | 57 +++++++++++++++---- apps/web/src/oj/problem/detail.vue | 2 + apps/web/src/oj/store/problem.ts | 10 ++++ 7 files changed, 101 insertions(+), 32 deletions(-) diff --git a/apps/web/src/oj/problem/components/BasicEditor.vue b/apps/web/src/oj/problem/components/BasicEditor.vue index f830663..04dfb2d 100644 --- a/apps/web/src/oj/problem/components/BasicEditor.vue +++ b/apps/web/src/oj/problem/components/BasicEditor.vue @@ -27,7 +27,8 @@ const editorHeight = computed(() => isDesktop.value ? "calc(100vh - 133px)" : "calc(100vh - 172px)", ) -onMounted(() => { +function loadCode() { + codeStore.code.language = problemStore.supportedLanguage(codeStore.code.language) const savedCode = storage.get(storageKey.value) codeStore.setCode( savedCode || @@ -35,7 +36,12 @@ onMounted(() => { SOURCES[codeStore.code.language], ) beginEditTrace(`problem_${problem.value!._id}_contest_${contestID}`, codeStore.code.value.length) -}) +} + +onMounted(loadCode) + +// 换题时组件复用、不重新挂载,和 ProblemEditor 一样得自己重新载入 +watch(() => problem.value?._id, loadCode) const changeCode = (v: string) => { storage.set(storageKey.value, v) diff --git a/apps/web/src/oj/problem/components/EditorToolbar.vue b/apps/web/src/oj/problem/components/EditorToolbar.vue index 0a103bf..625ef84 100644 --- a/apps/web/src/oj/problem/components/EditorToolbar.vue +++ b/apps/web/src/oj/problem/components/EditorToolbar.vue @@ -185,17 +185,20 @@ const handleMenuSelect = (key: string) => { } } -const languageOptions: DropdownOption[] = languages.value.map((it) => ({ - label: () => - h(NFlex, { align: "center" }, () => [ - h(Icon, { - icon: ICON_SET[it], - width: 16, - }), - LANGUAGE_SHOW_VALUE[it], - ]), - value: it, -})) +// computed:换题时组件复用,选项得跟着新题的语言走 +const languageOptions = computed(() => + languages.value.map((it) => ({ + label: () => + h(NFlex, { align: "center" }, () => [ + h(Icon, { + icon: ICON_SET[it], + width: 16, + }), + LANGUAGE_SHOW_VALUE[it], + ]), + value: it, + })), +) const copy = async () => { const success = await copyToClipboard(codeStore.code.value) @@ -247,12 +250,7 @@ const goEdit = () => { window.open(router.resolve(url).href, "_blank") } -onMounted(() => { - if (!languages.value.includes(codeStore.code.language)) { - // 回退到题目支持的第一种语言(如 SQL 题只有 "SQL",硬编码 Python 会被后端拒绝) - codeStore.code.language = languages.value[0] ?? "Python" - } -}) +// 语言回退不在这里做:它得排在载入草稿之前,见 problem store 的 supportedLanguage