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 }} - -