From 4993199fb1f551f5b381bc3eebd1817bf29c08f7 Mon Sep 17 00:00:00 2001 From: xuans Date: Thu, 17 Sep 2026 11:48:00 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=88=9D=E5=A7=8B=E5=8C=96?= =?UTF-8?q?=E9=94=99=E8=AF=AF=E6=8F=90=E7=A4=BA=E8=A2=AB=E9=82=AE=E7=AE=B1?= =?UTF-8?q?=E5=90=8C=E6=AD=A5=E6=B8=85=E9=99=A4=E5=8F=8A=E8=A1=A8=E5=8D=95?= =?UTF-8?q?=E9=94=99=E4=BD=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/views/SetupWizard/DatabaseSetup.vue | 53 ++++++++++++++++--- .../src/views/SetupWizard/SetupWizard.css | 18 +++++++ frontend/src/views/SetupWizard/SetupWizard.js | 7 +-- .../src/views/SetupWizard/SetupWizard.test.js | 34 ++++++++++++ 4 files changed, 102 insertions(+), 10 deletions(-) diff --git a/frontend/src/views/SetupWizard/DatabaseSetup.vue b/frontend/src/views/SetupWizard/DatabaseSetup.vue index 3d8bbf7..f4ec3dd 100644 --- a/frontend/src/views/SetupWizard/DatabaseSetup.vue +++ b/frontend/src/views/SetupWizard/DatabaseSetup.vue @@ -17,7 +17,12 @@ const emit = defineEmits(["test"]);
diff --git a/frontend/src/views/SetupWizard/SetupWizard.css b/frontend/src/views/SetupWizard/SetupWizard.css index 8c73742..f758730 100644 --- a/frontend/src/views/SetupWizard/SetupWizard.css +++ b/frontend/src/views/SetupWizard/SetupWizard.css @@ -22,6 +22,22 @@ gap: 16px; } +.warning-card { + display: grid; + gap: 8px; + margin-top: 18px; + padding-top: 16px; + border-top: 1px solid rgba(255, 255, 255, 0.3); + font-size: 12px; + line-height: 1.7; + letter-spacing: 0; + overflow-wrap: anywhere; +} + +.warning-card strong { + font-size: 13px; +} + .setup-eyebrow { margin: 0 0 6px; color: #4d76b7; @@ -188,6 +204,7 @@ legend span { .setup-grid { min-width: 0; display: grid; + align-items: start; gap: 9px 12px; } @@ -202,6 +219,7 @@ legend span { label { min-width: 0; display: grid; + align-content: start; gap: 5px; margin-top: 8px; color: #34445f; diff --git a/frontend/src/views/SetupWizard/SetupWizard.js b/frontend/src/views/SetupWizard/SetupWizard.js index bb75d9e..3178a14 100644 --- a/frontend/src/views/SetupWizard/SetupWizard.js +++ b/frontend/src/views/SetupWizard/SetupWizard.js @@ -247,9 +247,9 @@ export function useSetupWizard(props, emit) { emailAutofillElement.value.value = String(value || ""); } - function handleEmailInput(value) { + function handleEmailInput(value, clearError = true) { emailVisibleEdited = true; - error.value = ""; + if (clearError) error.value = ""; const rawValue = String(value || "").trim(); if (!rawValue) { @@ -314,7 +314,8 @@ export function useSetupWizard(props, emit) { if (!rawValue) return; if (rawValue.includes("@") || rawValue !== emailLocalPart.value) { - handleEmailInput(rawValue); + // 自动同步不应清除数据库、密码等其他字段的校验结果。 + handleEmailInput(rawValue, false); return; } diff --git a/frontend/src/views/SetupWizard/SetupWizard.test.js b/frontend/src/views/SetupWizard/SetupWizard.test.js index 33022bc..7648342 100644 --- a/frontend/src/views/SetupWizard/SetupWizard.test.js +++ b/frontend/src/views/SetupWizard/SetupWizard.test.js @@ -19,6 +19,40 @@ test("已有初始化服务商选择保持兼容", async (t) => { assert.equal(state.form.value.dns_provider, "cloudflare"); }); +test("邮箱定时同步不能清除步骤校验错误,手动编辑仍可清除", async (t) => { + const { state, runIntervals } = await mountComposable(t, + () => useSetupWizard({ status: { mode: "bootstrap" } }, () => {}), + async () => Response.json({ items: [aliyunProvider] })); + Object.assign(state.form.value, { + admin_username: "test-admin", + admin_password: "TestPass123", + confirm_password: "TestPass123", + web_hostname: "scert.example.test", + }); + state.emailInputElement.value = { value: "admin@example.test" }; + state.emailAutofillElement.value = { value: "" }; + state.handleEmailInput("admin@example.test"); + state.handleSubmit(); + assert.equal(state.error.value, "请先验证所选数据库的连接和写权限。"); + for (let i = 0; i < 8; i += 1) runIntervals(); + assert.equal(state.error.value, "请先验证所选数据库的连接和写权限。"); + assert.equal(state.currentStep.value, 1); + state.handleEmailInput("changed@example.test"); + assert.equal(state.error.value, ""); +}); + +test("自动填充同步新邮箱时保留其他字段的错误", async (t) => { + const { state, runIntervals } = await mountComposable(t, + () => useSetupWizard({ status: {} }, () => {}), + async () => Response.json({ items: [aliyunProvider] })); + state.emailInputElement.value = { value: "" }; + state.emailAutofillElement.value = { value: "autofill@example.test" }; + state.error.value = "两次输入的超级管理员密码不一致。"; + runIntervals(); + assert.equal(state.form.value.admin_email, "autofill@example.test"); + assert.equal(state.error.value, "两次输入的超级管理员密码不一致。"); +}); + async function setup(t, request) { const mounted = await mountComposable(t, () => useSetupWizard({ status: { dns_provider: "aliyun" } }, () => {}), async (path) => path.endsWith("/providers") ? Response.json({ items: [aliyunProvider] }) : request());