From 87c902c5da91cb19f676bca2873b0f9c53f1d55c Mon Sep 17 00:00:00 2001 From: liangxu Date: Mon, 27 Apr 2026 12:35:03 +0800 Subject: [PATCH] refactor(publish): replace inline banners with notifications and popover error preview - Switch retry/copy/console feedback from inline banners to antd notifications so the table layout stops jumping on each action. - Truncate the error message in the table cell and move full text + copy button into a hover popover, preventing very long adapter errors from blowing out the row width. - Pin column widths and force fixed table layout so the meta column no longer expands the table off-screen on long error strings. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../renderer/views/PublishManagementView.vue | 231 ++++++++++++++---- 1 file changed, 187 insertions(+), 44 deletions(-) diff --git a/apps/desktop-client/src/renderer/views/PublishManagementView.vue b/apps/desktop-client/src/renderer/views/PublishManagementView.vue index 27d68a8..bf2c373 100644 --- a/apps/desktop-client/src/renderer/views/PublishManagementView.vue +++ b/apps/desktop-client/src/renderer/views/PublishManagementView.vue @@ -9,6 +9,7 @@ import { SendOutlined, } from "@ant-design/icons-vue"; import type { DesktopPublishTaskListResponse, DesktopTaskInfo, JsonValue } from "@geo/shared-types"; +import { notification } from "ant-design-vue"; import { computed, onMounted, onUnmounted, ref, watch } from "vue"; import StatusBadge from "../components/StatusBadge.vue"; @@ -18,6 +19,8 @@ import { desktopPublishMediaCatalog } from "../lib/media-catalog"; import { normalizePublisherErrorMessage } from "../../shared/publisher-errors"; const PAGE_SIZE = 10; +const INLINE_ERROR_HEAD_CHARS = 48; +const INLINE_ERROR_TAIL_CHARS = 10; const publishPlatformIndex: Record = Object.fromEntries( desktopPublishMediaCatalog.map((item) => [item.id, item]), @@ -131,6 +134,15 @@ function normalizeTaskErrorMessage(message: string | null): string | null { return normalizePublisherErrorMessage(normalized) ?? normalized; } +function inlineErrorPreview(message: string): string { + const compact = message.replace(/\s+/g, " ").trim(); + const maxLength = INLINE_ERROR_HEAD_CHARS + INLINE_ERROR_TAIL_CHARS + 3; + if (compact.length <= maxLength) { + return compact; + } + return `${compact.slice(0, INLINE_ERROR_HEAD_CHARS)}...${compact.slice(-INLINE_ERROR_TAIL_CHARS)}`; +} + function summaryForTask(status: DesktopTaskInfo["status"]): string { switch (status) { case "queued": @@ -164,11 +176,26 @@ const searchTitle = ref(""); const appliedTitle = ref(""); const loading = ref(false); const error = ref(null); -const actionError = ref(null); const actionPendingTaskId = ref(null); const consolePendingTaskId = ref(null); const copiedErrorTaskId = ref(null); -const actionMessage = ref(null); + +function notifySuccess(message: string) { + notification.success({ + message, + placement: "topRight", + duration: 2.4, + }); +} + +function notifyActionError(description: string) { + notification.error({ + message: "操作失败", + description, + placement: "topRight", + duration: 4, + }); +} async function refreshTasks(page = currentPage.value) { loading.value = true; @@ -199,15 +226,13 @@ async function refreshTasks(page = currentPage.value) { async function retryTask(taskId: string) { actionPendingTaskId.value = taskId; - actionError.value = null; - actionMessage.value = null; try { await window.desktopBridge.app.retryPublishTask(taskId); - actionMessage.value = "已重新加入发布队列。"; + notifySuccess("已重新加入发布队列"); await refreshTasks(); } catch (err) { - actionError.value = err instanceof Error ? err.message : "重新发送失败"; + notifyActionError(err instanceof Error ? err.message : "重新发送失败"); } finally { actionPendingTaskId.value = null; } @@ -217,19 +242,17 @@ async function openExternalUrl(url: string | null) { if (!url) { return; } - actionError.value = null; try { await window.desktopBridge.app.openExternalUrl(url); } catch (err) { - actionError.value = err instanceof Error ? err.message : "打开外链失败"; + notifyActionError(err instanceof Error ? err.message : "打开外链失败"); } } async function openAccountWorkbench(record: PublishTaskItem) { const account = accountMap.value.get(record.accountId) ?? null; consolePendingTaskId.value = record.id; - actionError.value = null; try { await window.desktopBridge.app.openPublishAccountConsole({ @@ -239,7 +262,7 @@ async function openAccountWorkbench(record: PublishTaskItem) { displayName: account?.displayName ?? record.accountName, }); } catch (err) { - actionError.value = err instanceof Error ? err.message : "打开账号工作台失败"; + notifyActionError(err instanceof Error ? err.message : "打开账号工作台失败"); } finally { consolePendingTaskId.value = null; } @@ -267,18 +290,17 @@ async function copyErrorMessage(record: PublishTaskItem) { return; } - actionError.value = null; try { await copyTextToClipboard(record.errorMessage); copiedErrorTaskId.value = record.id; - actionMessage.value = "错误详情已复制。"; + notifySuccess("错误详情已复制"); window.setTimeout(() => { if (copiedErrorTaskId.value === record.id) { copiedErrorTaskId.value = null; } }, 1_500); } catch (err) { - actionError.value = err instanceof Error ? err.message : "复制错误详情失败"; + notifyActionError(err instanceof Error ? err.message : "复制错误详情失败"); } } @@ -368,12 +390,12 @@ const historyTotal = computed(() => taskPage.value?.history_total ?? 0); const totalCount = computed(() => taskPage.value?.total ?? 0); const tableColumns = [ - { title: "文章标题", key: "title", dataIndex: "title" }, - { title: "账号 / 平台", key: "account", dataIndex: "account" }, + { title: "文章标题", key: "title", dataIndex: "title", width: 280 }, + { title: "账号 / 平台", key: "account", dataIndex: "account", width: 180 }, { title: "状态", key: "status", dataIndex: "status", width: 130 }, - { title: "任务信息", key: "meta", dataIndex: "meta" }, - { title: "时间", key: "time", dataIndex: "time", width: 220 }, - { title: "操作", key: "actions", align: "right" as const, width: 120 }, + { title: "任务信息", key: "meta", dataIndex: "meta", width: 360 }, + { title: "时间", key: "time", dataIndex: "time", width: 210 }, + { title: "操作", key: "actions", align: "right" as const, width: 112 }, ]; @@ -412,9 +434,7 @@ const tableColumns = [ - -
@@ -504,22 +524,24 @@ const tableColumns = [
{{ record.summary }} - -