From 34ae9b032cf435dfffcee1f90320d685b6cf7701 Mon Sep 17 00:00:00 2001 From: yuetsh <517252939@qq.com> Date: Sat, 8 Aug 2026 05:19:23 -0600 Subject: [PATCH] =?UTF-8?q?fix(=E5=90=8E=E5=8F=B0):=20SQL=20=E6=B5=8B?= =?UTF-8?q?=E8=AF=95=E7=82=B9=E8=84=9A=E6=9C=AC=E8=AF=BB=E4=B8=8D=E5=87=BA?= =?UTF-8?q?=E6=9D=A5=E6=97=B6=E4=B8=8D=E8=83=BD=E9=9D=99=E9=BB=98=E7=95=99?= =?UTF-8?q?=E4=B8=80=E7=89=87=E7=A9=BA=E7=99=BD=E7=BC=96=E8=BE=91=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 用浏览器把前后台走了一遍(这是第一次真的在界面上验证,之前全是脚本打 API)。 唯一找到的真问题在 SQLTestcaseEditor: onMounted(async () => { try { ... } catch {} // ← 静默吞掉 }) 已有脚本读取失败时被 catch{} 吞掉,编辑器保持初始的 3 个空白项 —— 和「这题本来就没测试点」长得一模一样,教师完全看不出发生了什么。 改成:新题和旧格式测试点(404 problem-not-found / 409 not-sql-test-case)仍然 静默留空,那本来就是对的;其它失败挂一条 alert,并且把可操作的部分说全 —— 后端那句"测试点信息读取失败"只讲了现象,教师需要知道的是「下面是空模板、 直接存不会生效」。 保存本身是安全的,已实测:拿一道真实 SQL 题,在编辑器空白的状态下点提交, test_case_id、测试点数(3)、sql_config 全部未变 —— 后端读不到测试点信息会 拒绝整个保存(400),不会把测试点清空。所以这条只是提示缺失,不是数据风险。 ## 走查过程中的一次自我更正 中途我一度报告"保存返回 400 而界面没有任何错误提示",那是错的:提示是正常 显示的,我第一次等了 4 秒才检查,而 Naive UI 的提示 3 秒就自动消失了。 Co-Authored-By: Claude Opus 5 --- .../problem/components/SQLTestcaseEditor.vue | 25 ++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/apps/web/src/admin/problem/components/SQLTestcaseEditor.vue b/apps/web/src/admin/problem/components/SQLTestcaseEditor.vue index f1aa2ba..17324c0 100644 --- a/apps/web/src/admin/problem/components/SQLTestcaseEditor.vue +++ b/apps/web/src/admin/problem/components/SQLTestcaseEditor.vue @@ -44,6 +44,8 @@ const refSQL = computed( "", ) +/** 已有脚本读取失败时的提示。空白编辑器和「本来就没测试点」长得一样,必须区分开 */ +const loadError = ref("") const isPreviewing = ref(false) const isUploading = ref(false) const isGenerating = ref(false) @@ -79,7 +81,20 @@ onMounted(async () => { if (res.data.length) { scripts.value = res.data.map((f) => ({ ...blankEntry(), sql: f.content })) } - } catch {} + } catch (err: any) { + // 新题、以及旧格式(非 SQL)测试点,后端回 404/409,保持空白就是对的,不该报错。 + // 但**其它**失败必须说出来:读不出来时编辑器长得和「这题本来就没测试点」一模一样, + // 教师看不出区别,会以为要自己重新填。保存本身是安全的(后端读不到测试点信息会拒绝 + // 整个保存),所以这里只提示、不阻塞。 + const code = err?.error + if (code && code !== "problem-not-found" && code !== "not-sql-test-case") { + // 后端那句话(如"测试点信息读取失败")只说了现象,教师需要的是「下面是空的、别存」 + const detail = err?.data ? `(${err.data})` : "" + loadError.value = + `已有测试点脚本没能读出来${detail}。下方是空白模板,不是本题真实的测试点 —— ` + + `直接保存不会丢数据(后端会拒绝),但也不会生效。请先排查测试点文件,或重新上传。` + } + } }) function add() { @@ -195,6 +210,14 @@ async function upload() { > 还没有填写 SQL 标准答案,请先在上方"本题参考答案"中填写,再来编写测试点 + + {{ loadError }} + 清空