feat(desktop-client): queue account probes and report health to server

Replace serial probe-on-lock with a bounded probe queue (concurrency 3) that
adds a "queued" probe state, manual cooldown, and retry backoff. After each
probe the runtime debounces a batched POST to the new
/desktop/accounts/health-reports endpoint so the server learns about live,
expired, and risk transitions without waiting for a re-bind. Adds an
account-scoped IPC (probeRuntimeAccount + runtimeAccountSnapshot) so the
renderer can refresh a single row instead of replaying the full snapshot,
and exposes the resulting "重新校验" action in AccountsView/AiPlatformsView.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-27 21:33:55 +08:00
parent 051976e4a9
commit c3feb7477a
15 changed files with 817 additions and 129 deletions
+3 -1
View File
@@ -26,8 +26,10 @@ declare global {
user_id: number;
}): Promise<string>;
runtimeSnapshot(): Promise<DesktopRuntimeSnapshot>;
runtimeAccountSnapshot(accountId: string): Promise<DesktopRuntimeSnapshot["accounts"][number] | null>;
bindPublishAccount(platformId: string): Promise<DesktopAccountInfo>;
refreshRuntimeAccounts(): Promise<null>;
probeRuntimeAccount(accountId: string): Promise<DesktopRuntimeSnapshot["accounts"][number] | null>;
openPublishAccountConsole(account: {
id: string;
platform: string;
@@ -42,7 +44,7 @@ declare global {
releaseRuntimeSession(revoke?: boolean): Promise<null>;
setWindowMode(mode: "login" | "main"): Promise<null>;
onRuntimeInvalidated(
listener: (event: { reason: "account-health"; at: number }) => void,
listener: (event: { reason: "account-health"; at: number; accountId?: string }) => void,
): () => void;
onNetworkObserved(listener: (event: DesktopObservedRequest) => void): () => void;
};