fix(desktop): handle deepseek phone-number login in account name extractor

Phone-number logins return id_profile=null, mobile_number="177******08", and
email="" (empty string, not null). The previous fallback used `??`, which only
short-circuits on null/undefined, so an empty email string clobbered the
mobile_number fallback and the displayName ended up null — leaving the
DeepSeek card stuck on the "${label} 会话" placeholder.

Switch to a truthy pickString helper that requires a non-empty trimmed string
before accepting a candidate, and prefer mobile_number over email so the
masked phone number shows up exactly the way DeepSeek's own sidebar renders it.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-08 19:59:58 +08:00
parent 34b26e1079
commit bc8f1c353f
@@ -17,7 +17,12 @@ function normalizeText(value: unknown): string | null {
// DeepSeek (chat.deepseek.com) 没有 Redux/Pinia/window state,登录态只有 localStorage
// 里的 `userToken`JSON 包了 value 字段)。账号信息要走 /api/v0/users/current
// 用 Authorization: Bearer <token> 调。Cookie 不带 token,因此只能在页面上下文里
// 执行 fetch(自带 token,返回 biz_data.id_profile.{name, picture}
// 执行 fetch(自带 token)。
//
// 不同登录方式响应差异较大:
// 微信登录: id_profile = { provider: 'WECHAT', name: '阿白', picture: '...' }
// 手机登录: id_profile = null, mobile_number = '177******08'(其它字段是空串而非 null)
// 所以这里 fallback 必须用 truthy 判断而不是 ??,否则空串会击穿后续兜底。
//
// probe 通常在隐藏窗口、刚加载完就跑,React app 可能还没把 userToken 写入 localStorage
// 所以要 poll 一下直到 token 出现,再调 API。
@@ -60,14 +65,16 @@ export async function readDeepseekAccountIdentity(
});
if (!response.ok) return null;
const payload = await response.json().catch(() => null);
const profile = payload?.data?.biz_data?.id_profile ?? null;
const bizData = payload?.data?.biz_data ?? null;
const name = profile?.name ?? bizData?.email ?? bizData?.mobile_number ?? null;
const picture = profile?.picture ?? null;
return {
displayName: typeof name === 'string' ? name : null,
avatarUrl: typeof picture === 'string' ? picture : null,
};
const profile = bizData?.id_profile ?? null;
const pickString = (value) =>
typeof value === 'string' && value.trim() ? value : null;
const name =
pickString(profile?.name) ??
pickString(bizData?.mobile_number) ??
pickString(bizData?.email);
const picture = pickString(profile?.picture);
return { displayName: name, avatarUrl: picture };
} catch {
return null;
}