fix desktop account status display
This commit is contained in:
@@ -1,3 +1,8 @@
|
|||||||
|
import {
|
||||||
|
normalizeDesktopAccountErrorMessage,
|
||||||
|
translatePublisherPlatform,
|
||||||
|
} from '../../shared/publisher-errors'
|
||||||
|
|
||||||
type ClientErrorTone = 'error' | 'warning'
|
type ClientErrorTone = 'error' | 'warning'
|
||||||
type ClientActionKind = 'bind-account' | 'open-console' | 'probe-account' | 'unbind-account'
|
type ClientActionKind = 'bind-account' | 'open-console' | 'probe-account' | 'unbind-account'
|
||||||
|
|
||||||
@@ -48,7 +53,9 @@ function presentClientError(kind: ClientActionKind, error: unknown): ClientError
|
|||||||
return {
|
return {
|
||||||
tone: 'warning',
|
tone: 'warning',
|
||||||
title: '授权已中断',
|
title: '授权已中断',
|
||||||
content: '授权窗口已关闭,本次绑定没有完成。重新点击“绑定账号”即可继续。',
|
content:
|
||||||
|
normalizeDesktopAccountErrorMessage(message) ??
|
||||||
|
'授权窗口已关闭,本次绑定没有完成。重新点击“绑定账号”即可继续。',
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,7 +63,9 @@ function presentClientError(kind: ClientActionKind, error: unknown): ClientError
|
|||||||
return {
|
return {
|
||||||
tone: 'warning',
|
tone: 'warning',
|
||||||
title: '授权窗口已达上限',
|
title: '授权窗口已达上限',
|
||||||
content: '当前最多同时打开 2 个授权窗口。请先完成或关闭已有授权窗口,再继续新的绑定。',
|
content:
|
||||||
|
normalizeDesktopAccountErrorMessage(message) ??
|
||||||
|
'当前最多同时打开 2 个授权窗口。请先完成或关闭已有授权窗口,再继续新的绑定。',
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,7 +73,9 @@ function presentClientError(kind: ClientActionKind, error: unknown): ClientError
|
|||||||
return {
|
return {
|
||||||
tone: 'error',
|
tone: 'error',
|
||||||
title: '保存授权账号失败',
|
title: '保存授权账号失败',
|
||||||
content: '平台侧授权已经完成,但客户端回写账号信息失败。请稍后重试。',
|
content:
|
||||||
|
normalizeDesktopAccountErrorMessage(message) ??
|
||||||
|
'平台侧授权已经完成,但客户端回写账号信息失败。请稍后重试。',
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -72,7 +83,7 @@ function presentClientError(kind: ClientActionKind, error: unknown): ClientError
|
|||||||
return {
|
return {
|
||||||
tone: 'error',
|
tone: 'error',
|
||||||
title: '账号绑定失败',
|
title: '账号绑定失败',
|
||||||
content: '授权流程执行失败,请稍后重新发起绑定。',
|
content: normalizeDesktopAccountErrorMessage(message) ?? '授权流程执行失败,请稍后重新发起绑定。',
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,7 +92,9 @@ function presentClientError(kind: ClientActionKind, error: unknown): ClientError
|
|||||||
return {
|
return {
|
||||||
tone: 'error',
|
tone: 'error',
|
||||||
title: '平台暂不支持',
|
title: '平台暂不支持',
|
||||||
content: `${platformId} 暂时还不支持这个操作。`,
|
content:
|
||||||
|
normalizeDesktopAccountErrorMessage(message) ??
|
||||||
|
`${translatePublisherPlatform(platformId)}暂时还不支持这个操作。`,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -89,17 +102,20 @@ function presentClientError(kind: ClientActionKind, error: unknown): ClientError
|
|||||||
return {
|
return {
|
||||||
tone: 'warning',
|
tone: 'warning',
|
||||||
title: kind === 'unbind-account' ? '账号状态已变化' : '账号状态已更新',
|
title: kind === 'unbind-account' ? '账号状态已变化' : '账号状态已更新',
|
||||||
content: '当前账号状态刚刚发生了变化。请先刷新列表,再重试这次操作。',
|
content:
|
||||||
|
normalizeDesktopAccountErrorMessage(message) ??
|
||||||
|
'当前账号状态刚刚发生了变化。请先刷新列表,再重试这次操作。',
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (message.startsWith('desktop_account_session_expired:')) {
|
if (message.startsWith('desktop_account_session_expired:')) {
|
||||||
const platformId = message.split(':')[1] || '当前平台'
|
const platformId = message.split(':')[1] || '当前平台'
|
||||||
const platformLabel = platformId === 'qiehao' ? '企鹅号' : platformId
|
|
||||||
return {
|
return {
|
||||||
tone: 'warning',
|
tone: 'warning',
|
||||||
title: '授权已过期',
|
title: '授权已过期',
|
||||||
content: `${platformLabel} 登录态已失效,请重新授权后再打开工作台。`,
|
content:
|
||||||
|
normalizeDesktopAccountErrorMessage(message) ??
|
||||||
|
`${translatePublisherPlatform(platformId)}登录态已失效,请重新授权后再打开工作台。`,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -107,7 +123,17 @@ function presentClientError(kind: ClientActionKind, error: unknown): ClientError
|
|||||||
return {
|
return {
|
||||||
tone: 'error',
|
tone: 'error',
|
||||||
title: '账号解绑失败',
|
title: '账号解绑失败',
|
||||||
content: '服务端解绑没有成功完成,请稍后重试。',
|
content:
|
||||||
|
normalizeDesktopAccountErrorMessage(message) ?? '服务端解绑没有成功完成,请稍后重试。',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const normalizedDesktopMessage = normalizeDesktopAccountErrorMessage(message)
|
||||||
|
if (normalizedDesktopMessage) {
|
||||||
|
return {
|
||||||
|
tone: message.includes('expired') || message.includes('challenge') ? 'warning' : 'error',
|
||||||
|
title: '操作失败',
|
||||||
|
content: normalizedDesktopMessage,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ const batchProbeQueuedAccountIds = ref<readonly string[]>([])
|
|||||||
const batchProbeTotalCount = ref(0)
|
const batchProbeTotalCount = ref(0)
|
||||||
const actionSuccess = ref<string | null>(null)
|
const actionSuccess = ref<string | null>(null)
|
||||||
|
|
||||||
type AccountAuthState = 'authorized' | 'expired' | 'attention' | 'risk'
|
type AccountAuthState = 'authorized' | 'expired' | 'attention'
|
||||||
type AccountRow = Readonly<Omit<RuntimeAccount, 'tags'>> & { tags: readonly string[] }
|
type AccountRow = Readonly<Omit<RuntimeAccount, 'tags'>> & { tags: readonly string[] }
|
||||||
const publishPlatformIds = new Set(desktopPublishMediaCatalog.map((item) => item.id))
|
const publishPlatformIds = new Set(desktopPublishMediaCatalog.map((item) => item.id))
|
||||||
|
|
||||||
@@ -43,9 +43,8 @@ const accounts = computed(() =>
|
|||||||
)
|
)
|
||||||
|
|
||||||
const overview = computed(() => ({
|
const overview = computed(() => ({
|
||||||
authorized: accounts.value.filter((item) => item.health === 'live').length,
|
authorized: accounts.value.filter((item) => authState(item) === 'authorized').length,
|
||||||
attention: accounts.value.filter((item) => item.health === 'captcha').length,
|
attention: accounts.value.filter((item) => authState(item) !== 'authorized').length,
|
||||||
risk: accounts.value.filter((item) => item.health === 'risk').length,
|
|
||||||
onlineClients: snapshot.value?.summary.onlineClients ?? 0,
|
onlineClients: snapshot.value?.summary.onlineClients ?? 0,
|
||||||
}))
|
}))
|
||||||
|
|
||||||
@@ -76,7 +75,6 @@ const statusOptions = [
|
|||||||
{ value: 'all', label: '全部状态' },
|
{ value: 'all', label: '全部状态' },
|
||||||
{ value: 'authorized', label: '已授权' },
|
{ value: 'authorized', label: '已授权' },
|
||||||
{ value: 'attention', label: '待处理' },
|
{ value: 'attention', label: '待处理' },
|
||||||
{ value: 'risk', label: '风险观察' },
|
|
||||||
{ value: 'expired', label: '授权过期' },
|
{ value: 'expired', label: '授权过期' },
|
||||||
] as const
|
] as const
|
||||||
|
|
||||||
@@ -105,7 +103,7 @@ function authState(account: AccountRow): AccountAuthState {
|
|||||||
case 'challenge_required':
|
case 'challenge_required':
|
||||||
return 'attention'
|
return 'attention'
|
||||||
default:
|
default:
|
||||||
return 'risk'
|
return 'attention'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -117,15 +115,19 @@ function authStateLabel(account: AccountRow): string {
|
|||||||
return '校验中'
|
return '校验中'
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (authState(account)) {
|
switch (account.authState) {
|
||||||
case 'authorized':
|
case 'active':
|
||||||
return '已授权'
|
return '已授权'
|
||||||
case 'expired':
|
case 'expired':
|
||||||
return '授权过期'
|
return '授权过期'
|
||||||
case 'attention':
|
case 'revoked':
|
||||||
|
return '已停用'
|
||||||
|
case 'challenge_required':
|
||||||
return account.authReason === 'risk_control' ? '触发风控' : '需人工验证'
|
return account.authReason === 'risk_control' ? '触发风控' : '需人工验证'
|
||||||
default:
|
case 'expiring_soon':
|
||||||
return account.probeState === 'network_error' ? '最近校验失败' : '待重新校验'
|
return account.probeState === 'network_error' ? '最近校验失败' : '待重新校验'
|
||||||
|
default:
|
||||||
|
return account.probeState === 'network_error' ? '最近校验失败' : '待校验'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -134,13 +136,16 @@ function authTagColor(account: AccountRow): string {
|
|||||||
return 'processing'
|
return 'processing'
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (authState(account)) {
|
switch (account.authState) {
|
||||||
case 'authorized':
|
case 'active':
|
||||||
return 'success'
|
return 'success'
|
||||||
case 'expired':
|
case 'expired':
|
||||||
|
case 'revoked':
|
||||||
return 'error'
|
return 'error'
|
||||||
case 'attention':
|
case 'challenge_required':
|
||||||
return 'warning'
|
return 'warning'
|
||||||
|
case 'expiring_soon':
|
||||||
|
return account.probeState === 'network_error' ? 'warning' : 'default'
|
||||||
default:
|
default:
|
||||||
return 'default'
|
return 'default'
|
||||||
}
|
}
|
||||||
@@ -202,7 +207,7 @@ const filteredAccounts = computed(() => {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
if (selectedStatus.value !== 'all' && authState(account) !== selectedStatus.value) {
|
if (!matchesSelectedStatus(account)) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -223,6 +228,17 @@ const filteredAccounts = computed(() => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
function matchesSelectedStatus(account: AccountRow): boolean {
|
||||||
|
switch (selectedStatus.value) {
|
||||||
|
case 'all':
|
||||||
|
return true
|
||||||
|
case 'attention':
|
||||||
|
return authState(account) !== 'authorized'
|
||||||
|
default:
|
||||||
|
return authState(account) === selectedStatus.value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function selectPlatform(platform: string) {
|
function selectPlatform(platform: string) {
|
||||||
selectedPlatform.value = platform
|
selectedPlatform.value = platform
|
||||||
void refreshAccounts()
|
void refreshAccounts()
|
||||||
@@ -462,10 +478,6 @@ const tableColumns = [
|
|||||||
<div class="stat-label">待处理</div>
|
<div class="stat-label">待处理</div>
|
||||||
<div class="stat-value">{{ overview.attention }}</div>
|
<div class="stat-value">{{ overview.attention }}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="stat-card">
|
|
||||||
<div class="stat-label">风险观察</div>
|
|
||||||
<div class="stat-value">{{ overview.risk }}</div>
|
|
||||||
</div>
|
|
||||||
<div class="stat-card">
|
<div class="stat-card">
|
||||||
<div class="stat-label">在线客户端</div>
|
<div class="stat-label">在线客户端</div>
|
||||||
<div class="stat-value">{{ overview.onlineClients }}</div>
|
<div class="stat-value">{{ overview.onlineClients }}</div>
|
||||||
|
|||||||
@@ -18,15 +18,21 @@ export const DONGCHEDI_PLATFORM_EXCEPTION_MESSAGE =
|
|||||||
const PUBLISH_PLATFORM_LABELS: Record<string, string> = {
|
const PUBLISH_PLATFORM_LABELS: Record<string, string> = {
|
||||||
baijiahao: '百家号',
|
baijiahao: '百家号',
|
||||||
bilibili: 'bilibili',
|
bilibili: 'bilibili',
|
||||||
|
deepseek: 'DeepSeek',
|
||||||
dongchedi: '懂车帝',
|
dongchedi: '懂车帝',
|
||||||
|
doubao: '豆包',
|
||||||
jianshu: '简书',
|
jianshu: '简书',
|
||||||
juejin: '稀土掘金',
|
juejin: '稀土掘金',
|
||||||
|
kimi: 'Kimi',
|
||||||
qiehao: '企鹅号',
|
qiehao: '企鹅号',
|
||||||
|
qwen: '通义千问',
|
||||||
smzdm: '什么值得买',
|
smzdm: '什么值得买',
|
||||||
sohuhao: '搜狐号',
|
sohuhao: '搜狐号',
|
||||||
toutiaohao: '头条号',
|
toutiaohao: '头条号',
|
||||||
wangyihao: '网易号',
|
wangyihao: '网易号',
|
||||||
weixin_gzh: '微信公众号',
|
weixin_gzh: '微信公众号',
|
||||||
|
wenxin: '文心一言',
|
||||||
|
yuanbao: '混元 / 元宝',
|
||||||
zhihu: '知乎',
|
zhihu: '知乎',
|
||||||
zol: '中关村在线',
|
zol: '中关村在线',
|
||||||
}
|
}
|
||||||
@@ -36,6 +42,96 @@ function normalizeErrorText(value: string | null | undefined): string | null {
|
|||||||
return trimmed ? trimmed : null
|
return trimmed ? trimmed : null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function translatePublisherPlatform(platform: string | null | undefined): string {
|
||||||
|
const normalized = platform?.trim()
|
||||||
|
if (!normalized) {
|
||||||
|
return '当前平台'
|
||||||
|
}
|
||||||
|
return PUBLISH_PLATFORM_LABELS[normalized.toLowerCase()] ?? normalized
|
||||||
|
}
|
||||||
|
|
||||||
|
function errorPlatformSuffix(message: string, code: string): string | null {
|
||||||
|
const prefix = `${code}:`
|
||||||
|
return message.toLowerCase().startsWith(prefix)
|
||||||
|
? message.slice(prefix.length).trim() || null
|
||||||
|
: null
|
||||||
|
}
|
||||||
|
|
||||||
|
export function normalizeDesktopAccountErrorMessage(
|
||||||
|
message: string | null | undefined,
|
||||||
|
platform?: string | null,
|
||||||
|
): string | null {
|
||||||
|
const normalized = normalizeErrorText(message)
|
||||||
|
if (!normalized) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
const sessionExpiredPlatform = errorPlatformSuffix(
|
||||||
|
normalized,
|
||||||
|
'desktop_account_session_expired',
|
||||||
|
)
|
||||||
|
if (sessionExpiredPlatform !== null) {
|
||||||
|
const platformLabel = translatePublisherPlatform(sessionExpiredPlatform || platform)
|
||||||
|
return `${platformLabel}登录态已失效,请重新授权后再试。`
|
||||||
|
}
|
||||||
|
|
||||||
|
const unsupportedPlatform = errorPlatformSuffix(normalized, 'desktop_platform_not_supported')
|
||||||
|
if (unsupportedPlatform !== null) {
|
||||||
|
const platformLabel = translatePublisherPlatform(unsupportedPlatform || platform)
|
||||||
|
return `${platformLabel}暂时还不支持这个操作。`
|
||||||
|
}
|
||||||
|
|
||||||
|
const platformLabel = translatePublisherPlatform(platform)
|
||||||
|
switch (normalized) {
|
||||||
|
case 'desktop_account_bind_window_closed':
|
||||||
|
return '授权窗口已关闭,本次绑定没有完成。重新点击“绑定账号”即可继续。'
|
||||||
|
case 'desktop_account_bind_limit_reached':
|
||||||
|
return '当前最多同时打开 2 个授权窗口。请先完成或关闭已有授权窗口,再继续新的绑定。'
|
||||||
|
case 'desktop_account_upsert_failed':
|
||||||
|
return '平台侧授权已经完成,但客户端回写账号信息失败。请稍后重试。'
|
||||||
|
case 'desktop_account_bind_failed':
|
||||||
|
return '授权流程执行失败,请稍后重新发起绑定。'
|
||||||
|
case 'desktop_account_sync_conflict':
|
||||||
|
return '当前账号状态刚刚发生了变化。请先刷新列表,再重试这次操作。'
|
||||||
|
case 'desktop_account_delete_failed':
|
||||||
|
return '服务端解绑没有成功完成,请稍后重试。'
|
||||||
|
case 'desktop_account_auth_expired':
|
||||||
|
return platform
|
||||||
|
? `${platformLabel}登录态已失效,请重新授权后再试。`
|
||||||
|
: '发布账号登录态已失效,请重新授权后再试。'
|
||||||
|
case 'desktop_account_risk_control':
|
||||||
|
return platform
|
||||||
|
? `${platformLabel}账号疑似触发风控,请打开平台处理验证或等待限制解除后再重试。`
|
||||||
|
: '发布账号疑似触发风控,请打开平台处理验证或等待限制解除后再重试。'
|
||||||
|
case 'desktop_account_challenge_required':
|
||||||
|
return platform
|
||||||
|
? `${platformLabel}账号需要完成人机验证,请打开平台完成验证后再重试。`
|
||||||
|
: '发布账号需要完成人机验证,请打开平台完成验证后再重试。'
|
||||||
|
case 'desktop_account_probe_pending':
|
||||||
|
return platform
|
||||||
|
? `${platformLabel}账号最近校验失败,已暂缓执行任务。请刷新状态后再重试。`
|
||||||
|
: '发布账号最近校验失败,已暂缓执行任务。请刷新状态后再重试。'
|
||||||
|
case 'desktop_account_client_missing':
|
||||||
|
return '所选账号还没有绑定桌面客户端,暂时无法发布。'
|
||||||
|
case 'desktop_account_not_found':
|
||||||
|
return '所选桌面账号不存在,请刷新后重试。'
|
||||||
|
case 'desktop_account_not_publishable':
|
||||||
|
return '所选账号需要重新授权后才能发布。'
|
||||||
|
case 'desktop_account_lookup_failed':
|
||||||
|
return '查询桌面账号失败,请刷新后重试。'
|
||||||
|
case 'desktop_accounts_query_failed':
|
||||||
|
return '查询桌面账号列表失败,请刷新后重试。'
|
||||||
|
case 'desktop_account_sync_version_required_existing':
|
||||||
|
return '账号同步版本已失效,请刷新后重试。'
|
||||||
|
case 'desktop_account_patch_failed':
|
||||||
|
return '更新桌面账号失败,请稍后重试。'
|
||||||
|
case 'desktop_account_request_delete_failed':
|
||||||
|
return '更新账号解绑状态失败,请稍后重试。'
|
||||||
|
default:
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function isDongchediPlatform(platform?: string | null): boolean {
|
function isDongchediPlatform(platform?: string | null): boolean {
|
||||||
return platform?.trim().toLowerCase() === 'dongchedi'
|
return platform?.trim().toLowerCase() === 'dongchedi'
|
||||||
}
|
}
|
||||||
@@ -172,6 +268,10 @@ export function normalizePublisherErrorMessage(
|
|||||||
message: string | null | undefined,
|
message: string | null | undefined,
|
||||||
platform?: string | null,
|
platform?: string | null,
|
||||||
): string | null {
|
): string | null {
|
||||||
|
const desktopAccountMessage = normalizeDesktopAccountErrorMessage(message, platform)
|
||||||
|
if (desktopAccountMessage) {
|
||||||
|
return desktopAccountMessage
|
||||||
|
}
|
||||||
if (message === 'compliance_blocked') {
|
if (message === 'compliance_blocked') {
|
||||||
return '内容合规检测已阻断本次发布,请修改文章后重新发布。'
|
return '内容合规检测已阻断本次发布,请修改文章后重新发布。'
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user