feat(tenant): add brand publish-records list and harden enterprise site management
- Add GET /api/tenant/publish-records: brand-scoped paginated list that merges in-flight (queued/publishing) records ahead of history (success/failed/cancelled), enriched with article title and latest desktop task id; wire up service/handler/router/swagger/router_test - Rework PublishManagementView to consume publish-records instead of desktop publish tasks; add publishRecordsApi + shared-types (ListPublishRecordsParams, PublishRecordListResponse) - Enterprise site Update: distinguish explicit null from missing PATCH fields via EnterpriseSitePatchString, dedup site_url before write, verify RowsAffected, and map unique-constraint violations to a clear conflict - MediaView: enterprise site edit/delete flows with favicon fallback handling - Localize enterprise site / PBootCMS error messages to Chinese across the backend and the admin-web error map, plus legacy raw-message translation - deploy: gate migration-coupled service rollouts behind RUN_MIGRATIONS unless ALLOW_SKIP_MIGRATIONS_FOR_APP_ROLLOUT=true; handle empty SERVICES safely Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -33,7 +33,7 @@ import {
|
||||
tenantAccountsApi,
|
||||
} from '@/lib/api'
|
||||
import { coverUploadRequired, deriveCoverFileName } from '@/lib/cover-requirements'
|
||||
import { formatError } from '@/lib/errors'
|
||||
import { formatError, formatStoredErrorMessage } from '@/lib/errors'
|
||||
import {
|
||||
accountInitial,
|
||||
buildPublishAccountCards,
|
||||
@@ -876,7 +876,8 @@ async function handleEnterprisePublishSuccess(
|
||||
} else if (failed.length > 0) {
|
||||
notification.error({
|
||||
message: '企业站发布失败',
|
||||
description: failed[0]?.error_message || '请检查插件、栏目和 PBootCMS API 配置。',
|
||||
description:
|
||||
formatStoredErrorMessage(failed[0]?.error_message) || '请检查插件、栏目和 PBootCMS API 配置。',
|
||||
placement: 'topRight',
|
||||
duration: 6,
|
||||
})
|
||||
@@ -1094,14 +1095,14 @@ function resolveEnterpriseSiteDisabledReason(
|
||||
return '该企业站点已禁用。'
|
||||
}
|
||||
if (connectionStatus === 'error') {
|
||||
return site.last_error?.trim() || '该企业站点连接异常,请先测试连通性。'
|
||||
return formatStoredErrorMessage(site.last_error) || '该企业站点连接异常,请先测试连通性。'
|
||||
}
|
||||
return ''
|
||||
}
|
||||
|
||||
function enterpriseSiteConnectionStatus(site: EnterpriseSiteConnection): string {
|
||||
const status = String(site.status ?? '').trim()
|
||||
const lastError = site.last_error?.trim()
|
||||
const lastError = formatStoredErrorMessage(site.last_error)
|
||||
const publishError = enterpriseSiteLatestPublishError(site)
|
||||
if (status === 'error' && lastError && publishError && lastError === publishError) {
|
||||
return 'connected'
|
||||
@@ -1118,7 +1119,7 @@ function enterpriseSiteLatestPublishError(site: EnterpriseSiteConnection): strin
|
||||
if (status !== 'failed' && status !== 'publish_failed') {
|
||||
return ''
|
||||
}
|
||||
return record.error_message?.trim() || ''
|
||||
return formatStoredErrorMessage(record.error_message)
|
||||
}
|
||||
|
||||
function cmsTypeLabel(cmsType: string): string {
|
||||
|
||||
Reference in New Issue
Block a user