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:
2026-06-08 11:40:46 +08:00
parent 67be43319e
commit a44ed21967
15 changed files with 1418 additions and 764 deletions
+11
View File
@@ -85,6 +85,7 @@ import type {
KolWorkspaceCard,
ListCustomerSupplierMediaResourcesResponse,
ListDesktopPublishTasksParams,
ListPublishRecordsParams,
ListMediaSupplyOrdersParams,
ListMediaSupplyOrdersResponse,
ListMediaSupplyWalletLedgersParams,
@@ -116,6 +117,7 @@ import type {
PublishKolPromptRequest,
PublishEnterpriseSiteArticleRequest,
PublishRecord,
PublishRecordListResponse,
Question,
QuestionCandidateResult,
QuestionCombinationFillRequest,
@@ -345,6 +347,7 @@ const currentBrandScopedPathPatterns = [
/^\/api\/tenant\/schedules(?:\/|$)/,
/^\/api\/tenant\/instant-tasks(?:\/|$)/,
/^\/api\/tenant\/publish-jobs(?:\/|$)/,
/^\/api\/tenant\/publish-records(?:\/|$)/,
/^\/api\/tenant\/publish-tasks\/[^/]+\/retry(?:\/|$)/,
/^\/api\/tenant\/enterprise-sites\/[^/]+\/publish(?:\/|$)/,
/^\/api\/tenant\/media-supply\/orders(?:\/|$)/,
@@ -1386,6 +1389,14 @@ export const publishTasksApi = {
},
}
export const publishRecordsApi = {
list(params: ListPublishRecordsParams = {}) {
return apiClient.get<PublishRecordListResponse>('/api/tenant/publish-records', {
params,
})
},
}
export const enterpriseSitesApi = {
list() {
return apiClient.get<EnterpriseSiteConnection[]>('/api/tenant/enterprise-sites')