feat(article): support regenerating failed articles
This commit is contained in:
@@ -13,16 +13,16 @@ import type {
|
||||
BrandRequest,
|
||||
Competitor,
|
||||
CompetitorRequest,
|
||||
CreateArticleRequest,
|
||||
CreateKolPackageRequest,
|
||||
CreateKolPromptRequest,
|
||||
CreateAckRequest,
|
||||
ComplianceAckRecord,
|
||||
ComplianceCheckArticleRequest,
|
||||
ComplianceCheckPlainRequest,
|
||||
ComplianceCheckResult,
|
||||
ComplianceManualReview,
|
||||
ComplianceRuntimeStatus,
|
||||
CreateAckRequest,
|
||||
CreateArticleRequest,
|
||||
CreateKolPackageRequest,
|
||||
CreateKolPromptRequest,
|
||||
CreatePluginSessionRequest,
|
||||
CreatePluginSessionResponse,
|
||||
CreatePublishBatchRequest,
|
||||
@@ -92,6 +92,7 @@ import type {
|
||||
QuotaSummary,
|
||||
RecentArticle,
|
||||
RefreshResponse,
|
||||
RegenerateArticleResponse,
|
||||
RegisterPluginInstallationRequest,
|
||||
RegisterPluginInstallationResponse,
|
||||
ScheduleTask,
|
||||
@@ -626,6 +627,12 @@ export const articlesApi = {
|
||||
payload,
|
||||
)
|
||||
},
|
||||
regenerate(id: number) {
|
||||
return apiClient.post<RegenerateArticleResponse, null>(
|
||||
`/api/tenant/articles/${id}/regenerate`,
|
||||
null,
|
||||
)
|
||||
},
|
||||
detail(id: number) {
|
||||
return apiClient.get<ArticleDetail>(`/api/tenant/articles/${id}`)
|
||||
},
|
||||
@@ -1115,7 +1122,9 @@ export const complianceApi = {
|
||||
)
|
||||
},
|
||||
latestArticleCheck(articleId: number) {
|
||||
return apiClient.get<ComplianceCheckResult>(`/api/tenant/articles/${articleId}/compliance/latest`)
|
||||
return apiClient.get<ComplianceCheckResult>(
|
||||
`/api/tenant/articles/${articleId}/compliance/latest`,
|
||||
)
|
||||
},
|
||||
createAck(recordId: number, payload: CreateAckRequest) {
|
||||
return apiClient.post<ComplianceAckRecord, CreateAckRequest>(
|
||||
|
||||
@@ -6,9 +6,26 @@ export interface ArticleActionState {
|
||||
showPreview: boolean
|
||||
showCopy: boolean
|
||||
showDelete: boolean
|
||||
showRegenerate: boolean
|
||||
}
|
||||
|
||||
export function resolveArticleActionState(generateStatus?: string | null): ArticleActionState {
|
||||
export interface ArticleActionSource {
|
||||
generate_status?: string | null
|
||||
source_type?: string | null
|
||||
}
|
||||
|
||||
const regeneratableSourceTypes = new Set(['template', 'custom_generation', 'imitation', 'kol'])
|
||||
|
||||
export function resolveArticleActionState(
|
||||
articleOrGenerateStatus?: ArticleActionSource | string | null,
|
||||
): ArticleActionState {
|
||||
const generateStatus =
|
||||
typeof articleOrGenerateStatus === 'string'
|
||||
? articleOrGenerateStatus
|
||||
: articleOrGenerateStatus?.generate_status
|
||||
const sourceType =
|
||||
typeof articleOrGenerateStatus === 'string' ? undefined : articleOrGenerateStatus?.source_type
|
||||
|
||||
if (generateStatus === 'completed') {
|
||||
return {
|
||||
showPublish: true,
|
||||
@@ -16,6 +33,7 @@ export function resolveArticleActionState(generateStatus?: string | null): Artic
|
||||
showPreview: true,
|
||||
showCopy: true,
|
||||
showDelete: true,
|
||||
showRegenerate: false,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +44,7 @@ export function resolveArticleActionState(generateStatus?: string | null): Artic
|
||||
showPreview: false,
|
||||
showCopy: false,
|
||||
showDelete: true,
|
||||
showRegenerate: false,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,6 +55,7 @@ export function resolveArticleActionState(generateStatus?: string | null): Artic
|
||||
showPreview: false,
|
||||
showCopy: false,
|
||||
showDelete: true,
|
||||
showRegenerate: sourceType ? regeneratableSourceTypes.has(sourceType) : false,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,6 +65,7 @@ export function resolveArticleActionState(generateStatus?: string | null): Artic
|
||||
showPreview: true,
|
||||
showCopy: false,
|
||||
showDelete: true,
|
||||
showRegenerate: false,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
import type { ArticleListItem, RecentArticle } from '@geo/shared-types'
|
||||
import { useMutation, useQueryClient } from '@tanstack/vue-query'
|
||||
import { message } from 'ant-design-vue'
|
||||
import { ref } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
import { articlesApi } from '@/lib/api'
|
||||
import { formatError } from '@/lib/errors'
|
||||
|
||||
type RegeneratableArticle = Pick<ArticleListItem | RecentArticle, 'id'>
|
||||
|
||||
export function useArticleRegenerateAction() {
|
||||
const queryClient = useQueryClient()
|
||||
const { t } = useI18n()
|
||||
const regeneratingArticleId = ref<number | null>(null)
|
||||
|
||||
const regenerateMutation = useMutation({
|
||||
mutationFn: (article: RegeneratableArticle) => articlesApi.regenerate(article.id),
|
||||
onSuccess: async () => {
|
||||
message.success(t('common.regenerateSuccess'))
|
||||
regeneratingArticleId.value = null
|
||||
await Promise.all([
|
||||
queryClient.invalidateQueries({ queryKey: ['articles'] }),
|
||||
queryClient.invalidateQueries({ queryKey: ['workspace'] }),
|
||||
])
|
||||
},
|
||||
onError: (error) => {
|
||||
regeneratingArticleId.value = null
|
||||
message.error(formatError(error) || t('common.regenerateError'))
|
||||
},
|
||||
})
|
||||
|
||||
async function handleRegenerate(article: RegeneratableArticle): Promise<void> {
|
||||
regeneratingArticleId.value = article.id
|
||||
await regenerateMutation.mutateAsync(article)
|
||||
}
|
||||
|
||||
return {
|
||||
regeneratingArticleId,
|
||||
regenerateMutation,
|
||||
handleRegenerate,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user