Compare commits
4 Commits
5d29703265
...
8300d12b20
| Author | SHA1 | Date | |
|---|---|---|---|
| 8300d12b20 | |||
| 1bc4df958f | |||
| e90d6a185f | |||
| 58a9b379bc |
@@ -14,7 +14,6 @@ import type {
|
|||||||
ArticleListItem,
|
ArticleListItem,
|
||||||
ArticleListParams,
|
ArticleListParams,
|
||||||
KolWorkspaceCard,
|
KolWorkspaceCard,
|
||||||
RecentArticle,
|
|
||||||
TemplateListItem,
|
TemplateListItem,
|
||||||
} from '@geo/shared-types'
|
} from '@geo/shared-types'
|
||||||
import { useMutation, useQuery, useQueryClient } from '@tanstack/vue-query'
|
import { useMutation, useQuery, useQueryClient } from '@tanstack/vue-query'
|
||||||
@@ -94,17 +93,6 @@ const kolCardsQuery = useQuery({
|
|||||||
queryFn: () => workspaceApi.kolCards(),
|
queryFn: () => workspaceApi.kolCards(),
|
||||||
})
|
})
|
||||||
|
|
||||||
const recentArticlesQuery = useQuery({
|
|
||||||
queryKey: computed(() => [
|
|
||||||
'workspace',
|
|
||||||
'recent-articles',
|
|
||||||
'templates',
|
|
||||||
companyStore.currentBrandId,
|
|
||||||
]),
|
|
||||||
enabled: computed(() => Boolean(companyStore.currentBrandId)),
|
|
||||||
queryFn: () => workspaceApi.recentArticles(),
|
|
||||||
})
|
|
||||||
|
|
||||||
const articleParams = computed<ArticleListParams>(() => {
|
const articleParams = computed<ArticleListParams>(() => {
|
||||||
const params: ArticleListParams = {
|
const params: ArticleListParams = {
|
||||||
page: page.value,
|
page: page.value,
|
||||||
@@ -147,65 +135,11 @@ const articleListQuery = useQuery({
|
|||||||
queryFn: () => articlesApi.list(articleParams.value),
|
queryFn: () => articlesApi.list(articleParams.value),
|
||||||
})
|
})
|
||||||
|
|
||||||
const hasActiveRecordFilters = computed(() =>
|
|
||||||
Boolean(
|
|
||||||
appliedFilters.template_filter ||
|
|
||||||
appliedFilters.publish_status ||
|
|
||||||
appliedFilters.generate_status ||
|
|
||||||
appliedFilters.keyword?.trim() ||
|
|
||||||
appliedFilters.created_from ||
|
|
||||||
appliedFilters.created_to,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
const recentTemplateArticles = computed<ArticleListItem[]>(() =>
|
|
||||||
(recentArticlesQuery.data.value || [])
|
|
||||||
.filter(
|
|
||||||
(article: RecentArticle) =>
|
|
||||||
article.source_type === 'template' || article.source_type === 'kol',
|
|
||||||
)
|
|
||||||
.map((article: RecentArticle) => ({
|
|
||||||
id: article.id,
|
|
||||||
source_type: article.source_type,
|
|
||||||
template_id: null,
|
|
||||||
kol_prompt_id: null,
|
|
||||||
template_name:
|
|
||||||
article.template_name ||
|
|
||||||
(article.source_type === 'kol'
|
|
||||||
? t('templates.sections.refinedTemplates')
|
|
||||||
: t('templates.sections.generalTemplates')),
|
|
||||||
prompt_rule_id: null,
|
|
||||||
prompt_rule_name: null,
|
|
||||||
generation_mode: article.generation_mode,
|
|
||||||
auto_publish_platforms: [],
|
|
||||||
generate_status: article.generate_status,
|
|
||||||
publish_status: article.publish_status,
|
|
||||||
title: article.title,
|
|
||||||
generation_error_message: null,
|
|
||||||
word_count: article.word_count,
|
|
||||||
source_label: article.source_label,
|
|
||||||
created_at: article.created_at,
|
|
||||||
})),
|
|
||||||
)
|
|
||||||
|
|
||||||
const shouldUseRecentFallback = computed(
|
|
||||||
() =>
|
|
||||||
!hasActiveRecordFilters.value &&
|
|
||||||
(articleListQuery.data.value?.total ?? 0) === 0 &&
|
|
||||||
recentTemplateArticles.value.length > 0,
|
|
||||||
)
|
|
||||||
|
|
||||||
const displayedArticles = computed<ArticleListItem[]>(() =>
|
const displayedArticles = computed<ArticleListItem[]>(() =>
|
||||||
shouldUseRecentFallback.value
|
articleListQuery.data.value?.items || [],
|
||||||
? recentTemplateArticles.value
|
|
||||||
: articleListQuery.data.value?.items || [],
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const displayedArticleTotal = computed(() =>
|
const displayedArticleTotal = computed(() => articleListQuery.data.value?.total || 0)
|
||||||
shouldUseRecentFallback.value
|
|
||||||
? recentTemplateArticles.value.length
|
|
||||||
: articleListQuery.data.value?.total || 0,
|
|
||||||
)
|
|
||||||
|
|
||||||
let articlePollingTimer: number | null = null
|
let articlePollingTimer: number | null = null
|
||||||
const ARTICLE_LIST_POLL_INTERVAL_MS = 5000
|
const ARTICLE_LIST_POLL_INTERVAL_MS = 5000
|
||||||
@@ -287,18 +221,14 @@ const articleColumns = computed<TableColumnsType<ArticleListItem>>(() => [
|
|||||||
},
|
},
|
||||||
])
|
])
|
||||||
|
|
||||||
const articlePagination = computed(() =>
|
const articlePagination = computed(() => ({
|
||||||
shouldUseRecentFallback.value
|
current: page.value,
|
||||||
? false
|
pageSize: pageSize.value,
|
||||||
: {
|
total: displayedArticleTotal.value,
|
||||||
current: page.value,
|
showSizeChanger: true,
|
||||||
pageSize: pageSize.value,
|
onChange: handleTableChange,
|
||||||
total: displayedArticleTotal.value,
|
onShowSizeChange: handleTableChange,
|
||||||
showSizeChanger: true,
|
}))
|
||||||
onChange: handleTableChange,
|
|
||||||
onShowSizeChange: handleTableChange,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
// removed wizard watch effect
|
// removed wizard watch effect
|
||||||
|
|
||||||
@@ -449,13 +379,6 @@ function startArticlePolling(): void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
articlePollingTimer = window.setInterval(() => {
|
articlePollingTimer = window.setInterval(() => {
|
||||||
if (shouldUseRecentFallback.value) {
|
|
||||||
if (!recentArticlesQuery.isFetching.value) {
|
|
||||||
void recentArticlesQuery.refetch()
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!articleListQuery.isFetching.value) {
|
if (!articleListQuery.isFetching.value) {
|
||||||
void articleListQuery.refetch()
|
void articleListQuery.refetch()
|
||||||
}
|
}
|
||||||
@@ -493,7 +416,7 @@ async function copyArticle(articleId: number): Promise<void> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function refreshRecords(): void {
|
function refreshRecords(): void {
|
||||||
void Promise.all([articleListQuery.refetch(), recentArticlesQuery.refetch()])
|
void articleListQuery.refetch()
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -602,7 +525,7 @@ function refreshRecords(): void {
|
|||||||
class="templates-view__desktop-table"
|
class="templates-view__desktop-table"
|
||||||
:columns="articleColumns"
|
:columns="articleColumns"
|
||||||
:data-source="displayedArticles"
|
:data-source="displayedArticles"
|
||||||
:loading="articleListQuery.isPending.value || recentArticlesQuery.isPending.value"
|
:loading="articleListQuery.isPending.value"
|
||||||
row-key="id"
|
row-key="id"
|
||||||
:pagination="articlePagination"
|
:pagination="articlePagination"
|
||||||
:scroll="{ x: 1068 }"
|
:scroll="{ x: 1068 }"
|
||||||
@@ -657,7 +580,7 @@ function refreshRecords(): void {
|
|||||||
|
|
||||||
<div class="templates-view__mobile-records">
|
<div class="templates-view__mobile-records">
|
||||||
<a-skeleton
|
<a-skeleton
|
||||||
v-if="articleListQuery.isPending.value || recentArticlesQuery.isPending.value"
|
v-if="articleListQuery.isPending.value"
|
||||||
active
|
active
|
||||||
:paragraph="{ rows: 6 }"
|
:paragraph="{ rows: 6 }"
|
||||||
/>
|
/>
|
||||||
@@ -720,7 +643,6 @@ function refreshRecords(): void {
|
|||||||
</article>
|
</article>
|
||||||
|
|
||||||
<a-pagination
|
<a-pagination
|
||||||
v-if="!shouldUseRecentFallback"
|
|
||||||
class="templates-view__mobile-pagination"
|
class="templates-view__mobile-pagination"
|
||||||
:current="page"
|
:current="page"
|
||||||
:page-size="pageSize"
|
:page-size="pageSize"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@geo/desktop-client",
|
"name": "@geo/desktop-client",
|
||||||
"version": "0.1.8",
|
"version": "0.1.9",
|
||||||
"private": true,
|
"private": true,
|
||||||
"description": "省心推客户端 — 连接和管理您的媒体账号,轻松发布和监控内容表现。",
|
"description": "省心推客户端 — 连接和管理您的媒体账号,轻松发布和监控内容表现。",
|
||||||
"author": {
|
"author": {
|
||||||
|
|||||||
@@ -110,24 +110,18 @@ const articlePublishStatusAggregateJoin = `
|
|||||||
BOOL_OR(latest.status_bucket = 'success') AS has_success,
|
BOOL_OR(latest.status_bucket = 'success') AS has_success,
|
||||||
BOOL_OR(latest.status_bucket = 'failed') AS has_failed
|
BOOL_OR(latest.status_bucket = 'failed') AS has_failed
|
||||||
FROM (
|
FROM (
|
||||||
SELECT DISTINCT ON (
|
SELECT DISTINCT ON (` + publishRecordTargetIdentityExprSQL + `)
|
||||||
COALESCE(pr.target_type, 'platform_account'),
|
|
||||||
COALESCE(pr.platform_account_id, pr.target_connection_id)
|
|
||||||
)
|
|
||||||
CASE
|
CASE
|
||||||
WHEN pr.status IN ('success', 'published', 'publish_success') THEN 'success'
|
WHEN pr.status IN ('success', 'published', 'publish_success') THEN 'success'
|
||||||
WHEN pr.status IN ('publishing', 'pending', 'queued', 'running') THEN 'publishing'
|
WHEN pr.status IN ('publishing', 'pending', 'queued', 'running') THEN 'publishing'
|
||||||
ELSE 'failed'
|
ELSE 'failed'
|
||||||
END AS status_bucket
|
END AS status_bucket
|
||||||
FROM publish_records pr
|
FROM publish_records pr
|
||||||
|
LEFT JOIN platform_accounts pa ON pa.id = pr.platform_account_id
|
||||||
WHERE pr.tenant_id = a.tenant_id
|
WHERE pr.tenant_id = a.tenant_id
|
||||||
AND pr.article_id = a.id
|
AND pr.article_id = a.id
|
||||||
AND pr.deleted_at IS NULL
|
AND pr.deleted_at IS NULL
|
||||||
ORDER BY
|
ORDER BY ` + publishRecordTargetIdentityExprSQL + `, pr.created_at DESC, pr.id DESC
|
||||||
COALESCE(pr.target_type, 'platform_account'),
|
|
||||||
COALESCE(pr.platform_account_id, pr.target_connection_id),
|
|
||||||
pr.created_at DESC,
|
|
||||||
pr.id DESC
|
|
||||||
) latest
|
) latest
|
||||||
) publish_status_summary ON true`
|
) publish_status_summary ON true`
|
||||||
|
|
||||||
|
|||||||
@@ -45,6 +45,12 @@ type monitoringArticleAliasInput struct {
|
|||||||
ExternalManageURL *string
|
ExternalManageURL *string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const publishRecordTargetIdentityExprSQL = `CASE
|
||||||
|
WHEN COALESCE(pr.target_type, 'platform_account') = 'enterprise_site'
|
||||||
|
THEN 'enterprise_site:' || COALESCE(pr.target_connection_id::TEXT, '')
|
||||||
|
ELSE 'platform_account:' || pr.platform_id || ':' || COALESCE(NULLIF(pa.platform_uid, ''), pr.platform_account_id::TEXT, '')
|
||||||
|
END`
|
||||||
|
|
||||||
func loadPublishableArticleMeta(ctx context.Context, tx pgx.Tx, tenantID, brandID, articleID int64) (*publishableArticleMeta, error) {
|
func loadPublishableArticleMeta(ctx context.Context, tx pgx.Tx, tenantID, brandID, articleID int64) (*publishableArticleMeta, error) {
|
||||||
var generateStatus string
|
var generateStatus string
|
||||||
var wizardStateJSON []byte
|
var wizardStateJSON []byte
|
||||||
@@ -664,9 +670,14 @@ func recalculatePublishBatchStatus(ctx context.Context, tx pgx.Tx, publishBatchI
|
|||||||
func recalculateArticlePublishStatus(ctx context.Context, tx pgx.Tx, tenantID, articleID int64) (string, error) {
|
func recalculateArticlePublishStatus(ctx context.Context, tx pgx.Tx, tenantID, articleID int64) (string, error) {
|
||||||
rows, err := tx.Query(ctx, `
|
rows, err := tx.Query(ctx, `
|
||||||
SELECT status
|
SELECT status
|
||||||
FROM publish_records
|
FROM (
|
||||||
WHERE tenant_id = $1 AND article_id = $2
|
SELECT DISTINCT ON (`+publishRecordTargetIdentityExprSQL+`) pr.status
|
||||||
AND deleted_at IS NULL
|
FROM publish_records pr
|
||||||
|
LEFT JOIN platform_accounts pa ON pa.id = pr.platform_account_id
|
||||||
|
WHERE pr.tenant_id = $1 AND pr.article_id = $2
|
||||||
|
AND pr.deleted_at IS NULL
|
||||||
|
ORDER BY `+publishRecordTargetIdentityExprSQL+`, pr.created_at DESC, pr.id DESC
|
||||||
|
) latest
|
||||||
`, tenantID, articleID)
|
`, tenantID, articleID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", response.ErrInternal(50055, "article_publish_status_query_failed", "failed to inspect article publish status")
|
return "", response.ErrInternal(50055, "article_publish_status_query_failed", "failed to inspect article publish status")
|
||||||
|
|||||||
@@ -231,3 +231,40 @@ func TestRecalculateArticlePublishStatusDefaultsToUnpublished(t *testing.T) {
|
|||||||
t.Fatalf("recalculateArticlePublishStatus() = %q, want unpublished", got)
|
t.Fatalf("recalculateArticlePublishStatus() = %q, want unpublished", got)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestRecalculateArticlePublishStatusUsesLatestRecordPerPublishTarget(t *testing.T) {
|
||||||
|
tx := &capturePublishDedupLookupTx{rows: emptyPublishDedupRows{}}
|
||||||
|
|
||||||
|
_, err := recalculateArticlePublishStatus(context.Background(), tx, 1, 2)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("recalculateArticlePublishStatus() error = %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
normalized := normalizeSQLWhitespace(tx.sql)
|
||||||
|
for _, want := range []string{
|
||||||
|
"SELECT DISTINCT ON",
|
||||||
|
"LEFT JOIN platform_accounts pa ON pa.id = pr.platform_account_id",
|
||||||
|
"pa.platform_uid",
|
||||||
|
"pr.platform_id",
|
||||||
|
"pr.created_at DESC, pr.id DESC",
|
||||||
|
} {
|
||||||
|
if !strings.Contains(normalized, want) {
|
||||||
|
t.Fatalf("recalculate article publish status SQL missing %q: %s", want, normalized)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestArticlePublishStatusAggregateUsesLatestRecordPerPublishTarget(t *testing.T) {
|
||||||
|
normalized := normalizeSQLWhitespace(articlePublishStatusAggregateJoin)
|
||||||
|
for _, want := range []string{
|
||||||
|
"SELECT DISTINCT ON",
|
||||||
|
"LEFT JOIN platform_accounts pa ON pa.id = pr.platform_account_id",
|
||||||
|
"pa.platform_uid",
|
||||||
|
"pr.platform_id",
|
||||||
|
"pr.created_at DESC, pr.id DESC",
|
||||||
|
} {
|
||||||
|
if !strings.Contains(normalized, want) {
|
||||||
|
t.Fatalf("article publish aggregate SQL missing %q: %s", want, normalized)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -104,7 +104,16 @@ func (q *Queries) GetQuotaSummary(ctx context.Context, tenantID int64) (int32, e
|
|||||||
}
|
}
|
||||||
|
|
||||||
const getRecentArticlesByBrand = `-- name: GetRecentArticlesByBrand :many
|
const getRecentArticlesByBrand = `-- name: GetRecentArticlesByBrand :many
|
||||||
SELECT a.id, a.brand_id, a.generate_status, a.publish_status, a.source_type, a.created_at,
|
SELECT a.id, a.brand_id, a.generate_status,
|
||||||
|
CASE
|
||||||
|
WHEN COALESCE(publish_status_summary.record_count, 0) = 0 THEN a.publish_status
|
||||||
|
WHEN COALESCE(publish_status_summary.has_publishing, false) THEN 'publishing'
|
||||||
|
WHEN COALESCE(publish_status_summary.has_success, false)
|
||||||
|
AND COALESCE(publish_status_summary.has_failed, false) THEN 'partial_success'
|
||||||
|
WHEN COALESCE(publish_status_summary.has_success, false) THEN 'success'
|
||||||
|
ELSE 'failed'
|
||||||
|
END AS publish_status,
|
||||||
|
a.source_type, a.created_at,
|
||||||
av.title, av.markdown_content, av.word_count, av.source_label,
|
av.title, av.markdown_content, av.word_count, av.source_label,
|
||||||
t.template_name,
|
t.template_name,
|
||||||
COALESCE(
|
COALESCE(
|
||||||
@@ -114,6 +123,37 @@ SELECT a.id, a.brand_id, a.generate_status, a.publish_status, a.source_type, a.c
|
|||||||
FROM articles a
|
FROM articles a
|
||||||
LEFT JOIN article_versions av ON av.id = a.current_version_id
|
LEFT JOIN article_versions av ON av.id = a.current_version_id
|
||||||
LEFT JOIN article_templates t ON t.id = a.template_id
|
LEFT JOIN article_templates t ON t.id = a.template_id
|
||||||
|
LEFT JOIN LATERAL (
|
||||||
|
SELECT COUNT(*) AS record_count,
|
||||||
|
BOOL_OR(latest.status_bucket = 'publishing') AS has_publishing,
|
||||||
|
BOOL_OR(latest.status_bucket = 'success') AS has_success,
|
||||||
|
BOOL_OR(latest.status_bucket = 'failed') AS has_failed
|
||||||
|
FROM (
|
||||||
|
SELECT DISTINCT ON (
|
||||||
|
CASE
|
||||||
|
WHEN COALESCE(pr.target_type, 'platform_account') = 'enterprise_site'
|
||||||
|
THEN 'enterprise_site:' || COALESCE(pr.target_connection_id::TEXT, '')
|
||||||
|
ELSE 'platform_account:' || pr.platform_id || ':' || COALESCE(NULLIF(pa.platform_uid, ''), pr.platform_account_id::TEXT, '')
|
||||||
|
END
|
||||||
|
)
|
||||||
|
CASE
|
||||||
|
WHEN pr.status IN ('success', 'published', 'publish_success') THEN 'success'
|
||||||
|
WHEN pr.status IN ('publishing', 'pending', 'queued', 'running') THEN 'publishing'
|
||||||
|
ELSE 'failed'
|
||||||
|
END AS status_bucket,
|
||||||
|
CASE
|
||||||
|
WHEN COALESCE(pr.target_type, 'platform_account') = 'enterprise_site'
|
||||||
|
THEN 'enterprise_site:' || COALESCE(pr.target_connection_id::TEXT, '')
|
||||||
|
ELSE 'platform_account:' || pr.platform_id || ':' || COALESCE(NULLIF(pa.platform_uid, ''), pr.platform_account_id::TEXT, '')
|
||||||
|
END AS target_identity
|
||||||
|
FROM publish_records pr
|
||||||
|
LEFT JOIN platform_accounts pa ON pa.id = pr.platform_account_id
|
||||||
|
WHERE pr.tenant_id = a.tenant_id
|
||||||
|
AND pr.article_id = a.id
|
||||||
|
AND pr.deleted_at IS NULL
|
||||||
|
ORDER BY target_identity, pr.created_at DESC, pr.id DESC
|
||||||
|
) latest
|
||||||
|
) publish_status_summary ON true
|
||||||
LEFT JOIN LATERAL (
|
LEFT JOIN LATERAL (
|
||||||
SELECT input_params_json
|
SELECT input_params_json
|
||||||
FROM generation_tasks
|
FROM generation_tasks
|
||||||
|
|||||||
@@ -11,7 +11,16 @@ SELECT COUNT(*) FROM brands
|
|||||||
WHERE tenant_id = sqlc.arg(tenant_id) AND deleted_at IS NULL;
|
WHERE tenant_id = sqlc.arg(tenant_id) AND deleted_at IS NULL;
|
||||||
|
|
||||||
-- name: GetRecentArticlesByBrand :many
|
-- name: GetRecentArticlesByBrand :many
|
||||||
SELECT a.id, a.brand_id, a.generate_status, a.publish_status, a.source_type, a.created_at,
|
SELECT a.id, a.brand_id, a.generate_status,
|
||||||
|
CASE
|
||||||
|
WHEN COALESCE(publish_status_summary.record_count, 0) = 0 THEN a.publish_status
|
||||||
|
WHEN COALESCE(publish_status_summary.has_publishing, false) THEN 'publishing'
|
||||||
|
WHEN COALESCE(publish_status_summary.has_success, false)
|
||||||
|
AND COALESCE(publish_status_summary.has_failed, false) THEN 'partial_success'
|
||||||
|
WHEN COALESCE(publish_status_summary.has_success, false) THEN 'success'
|
||||||
|
ELSE 'failed'
|
||||||
|
END AS publish_status,
|
||||||
|
a.source_type, a.created_at,
|
||||||
av.title, av.markdown_content, av.word_count, av.source_label,
|
av.title, av.markdown_content, av.word_count, av.source_label,
|
||||||
t.template_name,
|
t.template_name,
|
||||||
COALESCE(
|
COALESCE(
|
||||||
@@ -21,6 +30,37 @@ SELECT a.id, a.brand_id, a.generate_status, a.publish_status, a.source_type, a.c
|
|||||||
FROM articles a
|
FROM articles a
|
||||||
LEFT JOIN article_versions av ON av.id = a.current_version_id
|
LEFT JOIN article_versions av ON av.id = a.current_version_id
|
||||||
LEFT JOIN article_templates t ON t.id = a.template_id
|
LEFT JOIN article_templates t ON t.id = a.template_id
|
||||||
|
LEFT JOIN LATERAL (
|
||||||
|
SELECT COUNT(*) AS record_count,
|
||||||
|
BOOL_OR(latest.status_bucket = 'publishing') AS has_publishing,
|
||||||
|
BOOL_OR(latest.status_bucket = 'success') AS has_success,
|
||||||
|
BOOL_OR(latest.status_bucket = 'failed') AS has_failed
|
||||||
|
FROM (
|
||||||
|
SELECT DISTINCT ON (
|
||||||
|
CASE
|
||||||
|
WHEN COALESCE(pr.target_type, 'platform_account') = 'enterprise_site'
|
||||||
|
THEN 'enterprise_site:' || COALESCE(pr.target_connection_id::TEXT, '')
|
||||||
|
ELSE 'platform_account:' || pr.platform_id || ':' || COALESCE(NULLIF(pa.platform_uid, ''), pr.platform_account_id::TEXT, '')
|
||||||
|
END
|
||||||
|
)
|
||||||
|
CASE
|
||||||
|
WHEN pr.status IN ('success', 'published', 'publish_success') THEN 'success'
|
||||||
|
WHEN pr.status IN ('publishing', 'pending', 'queued', 'running') THEN 'publishing'
|
||||||
|
ELSE 'failed'
|
||||||
|
END AS status_bucket,
|
||||||
|
CASE
|
||||||
|
WHEN COALESCE(pr.target_type, 'platform_account') = 'enterprise_site'
|
||||||
|
THEN 'enterprise_site:' || COALESCE(pr.target_connection_id::TEXT, '')
|
||||||
|
ELSE 'platform_account:' || pr.platform_id || ':' || COALESCE(NULLIF(pa.platform_uid, ''), pr.platform_account_id::TEXT, '')
|
||||||
|
END AS target_identity
|
||||||
|
FROM publish_records pr
|
||||||
|
LEFT JOIN platform_accounts pa ON pa.id = pr.platform_account_id
|
||||||
|
WHERE pr.tenant_id = a.tenant_id
|
||||||
|
AND pr.article_id = a.id
|
||||||
|
AND pr.deleted_at IS NULL
|
||||||
|
ORDER BY target_identity, pr.created_at DESC, pr.id DESC
|
||||||
|
) latest
|
||||||
|
) publish_status_summary ON true
|
||||||
LEFT JOIN LATERAL (
|
LEFT JOIN LATERAL (
|
||||||
SELECT input_params_json
|
SELECT input_params_json
|
||||||
FROM generation_tasks
|
FROM generation_tasks
|
||||||
|
|||||||
Reference in New Issue
Block a user