fix: keep remote heartbeat UI side effect free

This commit is contained in:
2026-09-20 23:25:46 +08:00
parent 1d5c472e88
commit 15b0477b44
3 changed files with 35 additions and 12 deletions
@@ -401,17 +401,31 @@ public sealed class RemoteAgentHostedService(
var wechatRunning = GetBoolean(element, "wechatAvailable");
var sessionAvailable = GetBoolean(element, "sessionAvailable");
var sessionLocked = GetBoolean(element, "sessionLocked");
var accounts = await backend.AccountsAsync(cancellationToken);
// Heartbeats must not refresh UI identity. Binding already contains the verified identity;
// the explicit accounts API remains the only path that may inspect the profile.
var accounts = await backend.AccountsAsync(cancellationToken, refreshUiIdentity: false);
var identities = accounts.Select(account => new RemoteAccountIdentity(
account.AccountId,
account.IsUiBindingKnown && account.Binding is not null && string.Equals(account.BindingStatus, "Bound", StringComparison.Ordinal))).ToArray();
var activeAccountId = remote.ActiveAccountId;
var boundAccounts = accounts
.Where(account => account.IsUiBindingKnown && account.Binding is not null && string.Equals(account.BindingStatus, "Bound", StringComparison.Ordinal))
.Select(account => account.AccountId)
.Distinct(StringComparer.OrdinalIgnoreCase)
.ToArray();
if ((string.IsNullOrWhiteSpace(activeAccountId) || !identities.Any(identity => identity.Verified && string.Equals(identity.AccountId, activeAccountId, StringComparison.Ordinal)))
&& boundAccounts.Length == 1)
{
// A single verified binding is safe to use when the optional GUI value is empty or a display name.
activeAccountId = boundAccounts[0];
}
var activeAccountVerified = false;
if (remote.ActiveAccountId is { Length: > 0 })
if (activeAccountId is { Length: > 0 })
{
try
{
accountContext.SwitchTo(remote.ActiveAccountId, identities);
activeAccountVerified = accountContext.IsConfirmedFor(remote.ActiveAccountId);
accountContext.SwitchTo(activeAccountId, identities);
activeAccountVerified = accountContext.IsConfirmedFor(activeAccountId);
}
catch (WxAgentException)
{
@@ -427,7 +441,7 @@ public sealed class RemoteAgentHostedService(
: !sessionAvailable ? RemoteNodeStatus.WechatNotLoggedIn
: !activeAccountVerified ? RemoteNodeStatus.Degraded
: RemoteNodeStatus.Online;
return new BackendSnapshot(nodeStatus, wechatRunning, sessionAvailable, sessionLocked, remote.ActiveAccountId, 0, activeAccountVerified, identities);
return new BackendSnapshot(nodeStatus, wechatRunning, sessionAvailable, sessionLocked, activeAccountId, 0, activeAccountVerified, identities);
}
catch
{