diff --git a/apps/admin-web/src/lib/api.ts b/apps/admin-web/src/lib/api.ts index 8a1bd54..0d63dee 100644 --- a/apps/admin-web/src/lib/api.ts +++ b/apps/admin-web/src/lib/api.ts @@ -1292,6 +1292,13 @@ export const tenantAccountsApi = { list() { return apiClient.get('/api/tenant/accounts') }, + remove(id: string) { + return apiClient.remove<{ + account: DesktopAccountInfo + cancelled_queued_publish_task_count: number + completed_server_side_unbinding: boolean + }>(`/api/tenant/accounts/${encodeURIComponent(id)}`) + }, requestDelete(id: string, options?: { undo?: boolean }) { const query = options?.undo ? '?undo=true' : '' return apiClient.post( diff --git a/apps/admin-web/src/lib/errors.ts b/apps/admin-web/src/lib/errors.ts index 57629f8..bc00b07 100644 --- a/apps/admin-web/src/lib/errors.ts +++ b/apps/admin-web/src/lib/errors.ts @@ -140,6 +140,7 @@ const errorMessageMap: Record = { invalid_publish_enterprise_site_targets: '企业站点发布目标格式不正确', desktop_account_client_missing: '所选账号还没有绑定桌面客户端,暂时无法发布', desktop_account_not_found: '所选桌面账号不存在,请刷新后重试', + publish_task_cancel_account_unbind_failed: '解绑账号时取消排队发布任务失败,请稍后重试', desktop_client_offline: '当前登录账号的桌面客户端未在线,请先打开 desktop-client', desktop_publish_duplicate: '内容已在发布队列中,未重复提交', desktop_publish_job_store_unavailable: '发布队列暂时不可用,请稍后重试', diff --git a/apps/admin-web/src/lib/publish-account-cards.ts b/apps/admin-web/src/lib/publish-account-cards.ts index 1929506..f37d983 100644 --- a/apps/admin-web/src/lib/publish-account-cards.ts +++ b/apps/admin-web/src/lib/publish-account-cards.ts @@ -130,6 +130,9 @@ export function buildPublishAccountCard( } export function resolvePublishState(account: DesktopAccountInfo): PublishState { + if (account.delete_requested_at) { + return 'unavailable' + } if (resolveAccountHealth(account) !== 'live') { return 'unavailable' } @@ -250,6 +253,9 @@ export function resolvePlatformLogoUrl( } function resolvePublishStatusText(account: DesktopAccountInfo, publishState: PublishState): string { + if (account.delete_requested_at) { + return '此运行节点绑定正在解绑中,不会再接收新的发布任务。' + } if (publishState === 'immediate') { return '任务消费通道在线,发布任务会立即被桌面端领取执行。' } diff --git a/apps/admin-web/src/views/MediaView.vue b/apps/admin-web/src/views/MediaView.vue index 5d854fa..386d8ac 100644 --- a/apps/admin-web/src/views/MediaView.vue +++ b/apps/admin-web/src/views/MediaView.vue @@ -239,6 +239,23 @@ const requestAccountDeleteMutation = useMutation({ }, }) +const removeAccountMutation = useMutation({ + mutationFn: (id: string) => tenantAccountsApi.remove(id), + onSuccess: async (result) => { + const cancelledCount = result.cancelled_queued_publish_task_count ?? 0 + message.success( + cancelledCount > 0 + ? `已完成解绑,并取消 ${cancelledCount} 个排队发布任务` + : '已完成解绑', + ) + await accountsQuery.refetch() + }, + onError: (error) => message.error(formatError(error)), + onSettled: () => { + requestingAccountDeleteId.value = null + }, +}) + const loading = computed(() => platformsQuery.isPending.value || accountsQuery.isPending.value) const refreshing = computed( () => @@ -389,6 +406,9 @@ const downloadableReleasesError = computed(() => { }) function resolvePublishState(account: DesktopAccountInfo): PublishState { + if (account.delete_requested_at) { + return 'unavailable' + } if (resolveAccountHealth(account) !== 'live') { return 'unavailable' } @@ -399,6 +419,9 @@ function resolvePublishState(account: DesktopAccountInfo): PublishState { } function resolvePublishHint(account: DesktopAccountInfo, publishState: PublishState): string { + if (account.delete_requested_at) { + return '此运行节点绑定正在解绑中,不会再接收新的发布任务。' + } if (publishState === 'immediate') { return '' } @@ -703,10 +726,10 @@ async function handleConfirmUnbind(): Promise { unbindConfirmLoading.value = true try { requestingAccountDeleteId.value = unbindAccountTarget.value.id - await requestAccountDeleteMutation.mutateAsync({ id: unbindAccountTarget.value.id }) + await removeAccountMutation.mutateAsync(unbindAccountTarget.value.id) unbindModalOpen.value = false } catch (err) { - // Error is handled by requestAccountDeleteMutation onError + // Error is handled by removeAccountMutation onError } finally { unbindConfirmLoading.value = false } @@ -719,7 +742,8 @@ function undoUnbindAccount(account: MediaAccountCard): void { function isAccountDeleteRequestPending(accountId: string): boolean { return ( - requestAccountDeleteMutation.isPending.value && requestingAccountDeleteId.value === accountId + (requestAccountDeleteMutation.isPending.value || removeAccountMutation.isPending.value) && + requestingAccountDeleteId.value === accountId ) } @@ -1365,6 +1389,15 @@ function releaseSize(value?: number | null): string {