From 85fcf91da028554529d1e03e3efb4e558b470c3d Mon Sep 17 00:00:00 2001 From: xuans Date: Fri, 25 Sep 2026 22:55:08 +0800 Subject: [PATCH] =?UTF-8?q?=E5=B1=95=E7=A4=BA=E8=AF=81=E4=B9=A6=E9=80=90?= =?UTF-8?q?=E5=8F=B0=E9=83=A8=E7=BD=B2=E7=BB=93=E6=9E=9C=E5=B9=B6=E4=BF=AE?= =?UTF-8?q?=E6=AD=A3=E5=AF=86=E7=A0=81=E8=AE=A4=E8=AF=81=E6=8F=90=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/views/Dashboard/Dashboard.js | 25 ++++++ .../src/views/Dashboard/Dashboard.test.js | 2 + frontend/src/views/Dashboard/Dashboard.vue | 12 ++- .../src/views/Dashboard/DeploymentFeedback.js | 25 ++++++ .../src/views/Dashboard/DeploymentResult.css | 28 ++++++ .../views/Dashboard/DeploymentResult.test.js | 86 +++++++++++++++++++ .../src/views/Dashboard/DeploymentResult.vue | 63 ++++++++++++++ 7 files changed, 240 insertions(+), 1 deletion(-) create mode 100644 frontend/src/views/Dashboard/DeploymentFeedback.js create mode 100644 frontend/src/views/Dashboard/DeploymentResult.css create mode 100644 frontend/src/views/Dashboard/DeploymentResult.test.js create mode 100644 frontend/src/views/Dashboard/DeploymentResult.vue diff --git a/frontend/src/views/Dashboard/Dashboard.js b/frontend/src/views/Dashboard/Dashboard.js index ef0a6e5..bbff5f0 100644 --- a/frontend/src/views/Dashboard/Dashboard.js +++ b/frontend/src/views/Dashboard/Dashboard.js @@ -1,5 +1,6 @@ import { computed, onBeforeUnmount, onMounted, ref, watch } from "vue"; import { settingsPayload } from "./SettingsPayload.js"; +import { deploymentSummary, serverAuthLabel } from "./DeploymentFeedback.js"; const defaultDNSVerificationTimeoutSeconds = 60; const aliyunDNSVerificationTimeoutSeconds = 6; @@ -71,6 +72,8 @@ export function useDashboard() { const taskAttempts = ref([]); const taskDetailsLoading = ref(false); const taskDetailsError = ref(""); + const deploymentResult = ref(null); + const domainActionRunning = ref(false); const hasOpenModal = computed( () => showForm.value || @@ -78,6 +81,7 @@ export function useDashboard() { showSSHKeyForm.value || showSettings.value || showCertificateImport.value || + deploymentResult.value !== null || showTaskDetails.value, ); let previousBodyOverflow = ""; @@ -719,6 +723,11 @@ export function useDashboard() { } async function runDomainAction(item, action, successMessage) { + if (domainActionRunning.value) return; + domainActionRunning.value = true; + if (action === "deploy") { + deploymentResult.value = { domain: item.name, running: true, report: null, error: "" }; + } error.value = ""; notice.value = ""; try { @@ -729,12 +738,26 @@ export function useDashboard() { } const response = await fetchAdmin(`/api/v1/domains/${item.id}/${action}`, options); const result = await response.json().catch(() => ({})); + if (action === "deploy") { + deploymentResult.value = { + domain: item.name, + running: false, + report: result.deployment || null, + error: response.ok && result.deployment ? "" : result.error || deploymentSummary(null), + }; + } if (!response.ok) throw new Error(result.error || "域名操作失败"); notice.value = successMessage; + if (action === "deploy") notice.value = deploymentSummary(result.deployment); } catch (err) { error.value = err.message || "域名操作失败"; } finally { const actionError = error.value; + if (action === "deploy" && deploymentResult.value) { + deploymentResult.value.running = false; + if (actionError) deploymentResult.value.error = actionError; + } + domainActionRunning.value = false; await loadData(); if (actionError) error.value = actionError; } @@ -1262,6 +1285,7 @@ export function useDashboard() { dnsProviders, environmentLabels, webServerLabels, + serverAuthLabel, isEditing, formTitle, form, @@ -1319,6 +1343,7 @@ export function useDashboard() { taskAttempts, taskDetailsLoading, taskDetailsError, + deploymentResult, taskTypeLabel, auditActionLabel, taskStageLabel, diff --git a/frontend/src/views/Dashboard/Dashboard.test.js b/frontend/src/views/Dashboard/Dashboard.test.js index 734332d..6ed88d3 100644 --- a/frontend/src/views/Dashboard/Dashboard.test.js +++ b/frontend/src/views/Dashboard/Dashboard.test.js @@ -1,4 +1,5 @@ import assert from "node:assert/strict"; +import "./DeploymentResult.test.js"; import test from "node:test"; import { nextTick, ref } from "vue"; import { useDashboard } from "./Dashboard.js"; @@ -108,6 +109,7 @@ test("完整页面逐个渲染六个板块,每次只有一个内容标题", as app.component(name, { render: () => null }); } app.component("UserManagement", { render: () => Vue.h("h2", headings.users) }); + app.component("DeploymentResult", { render: () => null }); const warnings = []; app.config.warnHandler = (message) => warnings.push(message); const html = await renderToString(app); diff --git a/frontend/src/views/Dashboard/Dashboard.vue b/frontend/src/views/Dashboard/Dashboard.vue index db58bcf..dc72f0f 100644 --- a/frontend/src/views/Dashboard/Dashboard.vue +++ b/frontend/src/views/Dashboard/Dashboard.vue @@ -8,6 +8,7 @@ import SSHKeyModal from "./SSHKeyModal.vue"; import DashboardNavigation from "./DashboardNavigation.vue"; import { useDashboardNavigation } from "./DashboardNavigation.js"; import { useDashboard } from "./Dashboard.js"; +import DeploymentResult from "./DeploymentResult.vue"; const dashboard = useDashboard(); const { @@ -128,6 +129,8 @@ const { taskAttempts, taskDetailsLoading, taskDetailsError, + deploymentResult, + serverAuthLabel, displayLabel, formatDate, daysRemaining, @@ -471,7 +474,8 @@ const { activeSection, activeLabel, sections, selectSection } = useDashboardNavi
{{ item.username }}@{{ item.address }}:{{ item.port }}私钥引用已配置私钥引用已配置{{ serverAuthLabel(item) }}指纹:{{ item.host_key_fingerprint }}
@@ -550,6 +554,12 @@ const { activeSection, activeLabel, sections, selectSection } = useDashboardNavi + +