diff --git a/apps/desktop-client/src/renderer/views/PublishManagementView.vue b/apps/desktop-client/src/renderer/views/PublishManagementView.vue index 73eca11..bc2ca3b 100644 --- a/apps/desktop-client/src/renderer/views/PublishManagementView.vue +++ b/apps/desktop-client/src/renderer/views/PublishManagementView.vue @@ -116,6 +116,27 @@ function extractString(value: JsonValue | null | undefined): string | null { return trimmed ? trimmed : null; } +function extractStringId(value: JsonValue | null | undefined): string | null { + if (typeof value === "number" && Number.isFinite(value)) { + return String(Math.trunc(value)); + } + return extractString(value); +} + +function buildSohuArticleUrl(task: DesktopTaskInfo, result: Record): string | null { + if (task.platform !== "sohuhao" || extractString(result.publish_type) === "draft") { + return null; + } + + const articleId = extractStringId(result.external_article_id); + const accountUid = accountMap.value.get(task.target_account_id)?.platformUid?.trim() ?? ""; + if (!articleId || !accountUid) { + return null; + } + + return `https://www.sohu.com/a/${encodeURIComponent(articleId)}_${encodeURIComponent(accountUid)}`; +} + function normalizePublishTaskStatus(status: DesktopTaskInfo["status"]): DesktopTaskInfo["status"] { return status === "unknown" ? "failed" : status; } @@ -374,7 +395,7 @@ const publishTasks = computed(() => leaseExpiresAt: task.lease_expires_at ? parseTimestamp(task.lease_expires_at) : null, createdAt: parseTimestamp(task.created_at), updatedAt: parseTimestamp(task.updated_at), - externalArticleUrl: extractString(result.external_article_url), + externalArticleUrl: extractString(result.external_article_url) ?? buildSohuArticleUrl(task, result), externalManageUrl: extractString(result.external_manage_url), errorMessage: normalizeTaskErrorMessage( extractString(taskError.message) @@ -403,66 +424,65 @@ const tableScroll = { x: 1000 } as const; @@ -639,135 +660,97 @@ const tableScroll = { x: 1000 } as const; .page-container { display: flex; flex-direction: column; - gap: 16px; + gap: 32px; padding-bottom: 40px; max-width: 1400px; } -/* Header Bar */ -.page-header { - display: flex; - align-items: center; - gap: 20px; - flex-wrap: wrap; +/* Hero Section (aligned with AccountsView) */ +.hero-card { + background: #ffffff; + border-radius: 20px; + border: 1px solid #eef2f6; + box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.02), 0 2px 4px -2px rgba(0, 0, 0, 0.01); + overflow: hidden; } -.page-header__title { +.hero-header { display: flex; - flex-direction: column; - gap: 2px; - min-width: 0; + justify-content: space-between; + align-items: flex-start; + padding: 36px 40px; } .eyebrow { - margin: 0; - color: #94a3b8; - font-size: 11px; + margin: 0 0 12px; + color: #64748b; + font-size: 13px; font-weight: 700; - letter-spacing: 0.12em; + letter-spacing: 0.1em; text-transform: uppercase; } -.page-header__title h2 { +.hero-title h2 { margin: 0; - font-size: 22px; - font-weight: 700; + font-size: 32px; + font-weight: 800; color: #0f172a; - letter-spacing: -0.01em; - line-height: 1.2; + letter-spacing: -0.02em; } -.page-header__metrics { +.modern-btn { + border-radius: 8px; + height: 40px; + padding: 0 20px; + font-weight: 600; +} + +/* Stats Strip */ +.stats-strip { display: flex; - gap: 8px; - margin-left: auto; - flex-wrap: wrap; + padding: 24px 40px; + background: #f8fafc; + border-top: 1px solid #eef2f6; + gap: 40px; } -.metric { +.stat-card { display: flex; flex-direction: column; - gap: 2px; - align-items: flex-start; - min-width: 76px; - padding: 8px 14px; - border-radius: 10px; - background: #ffffff; - border: 1px solid #e6edf5; + gap: 8px; + flex: 1; } -.metric--accent { - border-color: #fcd34d; - background: #fffbeb; -} - -.metric--total { - background: #f8fafc; -} - -.metric__label { - color: #64748b; - font-size: 11px; +.stat-label { + font-size: 14px; font-weight: 500; + color: #64748b; } -.metric__value { - color: #0f172a; - font-size: 18px; +.stat-value { + font-size: 40px; font-weight: 700; - line-height: 1.1; + color: #0f172a; + line-height: 1; font-feature-settings: "tnum"; } -.metric--accent .metric__value { +.stat-value--accent { color: #b45309; } -.page-header__actions { - display: flex; - align-items: center; -} - -.ghost-btn { - border-radius: 8px; - height: 36px; - padding: 0 14px; - font-weight: 500; - border-color: #e2e8f0; - color: #475569; -} -.ghost-btn:hover, -.ghost-btn:focus { - border-color: #cbd5e1; - color: #0f172a; - background: #f8fafc; -} - -.page-summary { - margin: 0; - color: #64748b; - font-size: 13px; - line-height: 1.5; -} - -/* Data Card */ -.data-card { - background: #ffffff; - border-radius: 16px; - border: 1px solid #eef2f6; - box-shadow: 0 1px 2px rgba(15, 23, 42, 0.03); - overflow: hidden; +/* Content Section / Table Toolbar */ +.content-section { display: flex; flex-direction: column; + gap: 24px; } -.data-card__toolbar { - display: flex; - align-items: flex-end; - justify-content: space-between; - gap: 16px; - padding: 18px 20px; +.table-toolbar { + padding: 24px 32px 16px; border-bottom: 1px solid #eef2f6; + align-items: center; + gap: 16px; flex-wrap: wrap; } @@ -778,21 +761,21 @@ const tableScroll = { x: 1000 } as const; .section-title { margin: 0; - font-size: 15px; + font-size: 20px; font-weight: 700; color: #0f172a; } .section-desc { - margin: 4px 0 0; + margin: 6px 0 0; color: #64748b; - font-size: 12px; + font-size: 13px; line-height: 1.5; } .toolbar-filters { display: flex; - gap: 8px; + gap: 12px; align-items: center; flex-shrink: 0; } @@ -802,30 +785,27 @@ const tableScroll = { x: 1000 } as const; border-radius: 8px; } -.primary-btn { - border-radius: 8px; - height: 32px; - padding: 0 16px; - font-weight: 500; +/* Modern Enterprise Table (aligned with AccountsView) */ +:deep(.publish-table) { + padding: 0 32px 16px; } -/* Table */ :deep(.publish-table .ant-table) { background: transparent; } :deep(.publish-table .ant-table-thead > tr > th) { - background-color: #fafbfc !important; + background-color: transparent !important; color: #64748b; font-weight: 600; - font-size: 12px; + font-size: 13px; border-bottom: 1px solid #e2e8f0; - padding: 10px 14px; + padding: 16px 12px; white-space: nowrap; } :deep(.publish-table .ant-table-tbody > tr > td) { - padding: 12px 14px; + padding: 16px 12px; border-bottom: 1px solid #f1f5f9; color: #0f172a; vertical-align: middle; @@ -874,7 +854,7 @@ const tableScroll = { x: 1000 } as const; .cell-title { font-weight: 600; color: #0f172a; - font-size: 13px; + font-size: 14px; line-height: 1.4; display: block; overflow: hidden; @@ -885,14 +865,15 @@ const tableScroll = { x: 1000 } as const; .cell-title--mono { font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace; font-weight: 500; - font-size: 12.5px; + font-size: 13px; } .cell-sub { color: #64748b; - font-size: 12px; + font-size: 13px; line-height: 1.5; display: block; + margin-top: 4px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; @@ -1055,8 +1036,7 @@ const tableScroll = { x: 1000 } as const; display: flex; align-items: center; justify-content: flex-end; - padding: 12px 20px; - border-top: 1px solid #eef2f6; + padding: 16px 32px 24px; background: transparent; }