From ca99f0ea7ff9ab8fe8c1fb67bc4ff44230b52c54 Mon Sep 17 00:00:00 2001 From: logan Date: Sun, 24 May 2026 15:37:08 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E5=B7=A5=E5=8D=95=E6=8F=90=E4=BA=A4422?= =?UTF-8?q?=E9=94=99=E8=AF=AF=E5=A4=84=E7=90=86=20+=20SQL=E6=A8=A1?= =?UTF-8?q?=E6=9D=BF=E5=8D=A0=E4=BD=8D=E7=AC=A6=E6=A0=A1=E9=AA=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - TicketCreatePage: Pydantic 422 detail 是对象数组,前端错误处理改为检测数组并拼接 msg - QueriesPage: 执行前检查 SQL 中未替换的 {table}/{db}/{collection} 占位符,阻止执行 - QueriesPage: 同步修复 422 detail 数组的错误处理 --- frontend/src/pages/QueriesPage.tsx | 7 ++++++- frontend/src/pages/TicketCreatePage.tsx | 6 ++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/frontend/src/pages/QueriesPage.tsx b/frontend/src/pages/QueriesPage.tsx index 37c1f96..ee5db62 100644 --- a/frontend/src/pages/QueriesPage.tsx +++ b/frontend/src/pages/QueriesPage.tsx @@ -343,6 +343,10 @@ function NewQueryPanel({ const handleExecute = useCallback(async () => { if (!sql || !instanceId) { setError('请选择实例并输入查询语句'); return; } + // 检查未替换的模板占位符 + if (/\{(?:table|db|collection)\}/.test(sql)) { + setError('SQL 中含有未替换的占位符 {table}/{db}/{collection},请先替换或删除'); return; + } setExecuting(true); setError(''); setResult(null); @@ -368,7 +372,8 @@ function NewQueryPanel({ favorite: false, }); } catch (e: unknown) { - const msg = (e as { response?: { data?: { detail?: string } } })?.response?.data?.detail || '查询失败'; + const raw = (e as { response?: { data?: { detail?: string | Array<{ msg: string }> } } })?.response?.data?.detail; + const msg = Array.isArray(raw) ? raw.map((v) => v.msg).join('; ') : (raw || '查询失败'); setError(msg); onExecuted({ id: Date.now(), diff --git a/frontend/src/pages/TicketCreatePage.tsx b/frontend/src/pages/TicketCreatePage.tsx index 42f727c..b4cef7f 100644 --- a/frontend/src/pages/TicketCreatePage.tsx +++ b/frontend/src/pages/TicketCreatePage.tsx @@ -398,8 +398,10 @@ export default function TicketCreatePage() { }); navigate('/tickets'); } catch (e: unknown) { - const err = e as { response?: { data?: { detail?: string } } }; - setError(err?.response?.data?.detail || '提交失败,请稍后重试'); + const err = e as { response?: { data?: { detail?: string | Array<{ msg: string }> } } }; + const raw = err?.response?.data?.detail; + const msg = Array.isArray(raw) ? raw.map((v) => v.msg).join('; ') : (raw || '提交失败,请稍后重试'); + setError(msg); } finally { setSubmitting(false); } }, [title, sqlContent, instanceId, database, reason, priority, rollbackSql, instances, dbType, navigate]);