From ed2920275dbfa6ba47dd2279afdbf3329874f221 Mon Sep 17 00:00:00 2001 From: Your Name Date: Fri, 25 Sep 2026 00:49:06 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E8=B5=84=E6=96=99=E5=BC=B9?= =?UTF-8?q?=E7=AA=97=E7=82=B9=E5=87=BB=E8=87=AA=E5=B7=B1=E5=A4=B4=E5=83=8F?= =?UTF-8?q?=E5=BF=85=E5=AE=9A=E5=8A=A0=E8=BD=BD=E5=A4=B1=E8=B4=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GET /users/{id}/profile 对自己的id恒定400(和更早修过的群内自己资料 400是同一类self-lookup限制),点击群成员格子/列表里自己的头像会一直 显示"加载失败,请重试"。改成自己走专门的 GET /me/profile(没有这个 限制),归一化成和他人资料相同的字段结构供同一套渲染逻辑使用。 Co-Authored-By: Claude Sonnet 5 --- web/src/app/UserCardRoot.tsx | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/web/src/app/UserCardRoot.tsx b/web/src/app/UserCardRoot.tsx index 53d6753a..51d79a97 100644 --- a/web/src/app/UserCardRoot.tsx +++ b/web/src/app/UserCardRoot.tsx @@ -8,6 +8,7 @@ import { Icon } from '@/app/Icon'; import { AddFriendModal } from '@/features/contacts/AddFriendModal'; import { ImApiError } from '@/lib/api/client'; import { getUserProfile } from '@/lib/api/friends'; +import { getMyProfile } from '@/lib/api/profile'; import { useEscapeKey } from '@/lib/hooks'; import { useCallStore } from '@/stores/calls'; import { useSessionStore } from '@/stores/session'; @@ -40,11 +41,40 @@ function UserCardPanel({ userId }: { userId: string }) { const isSelf = !!myUserId && myUserId === userId; const [addingFriend, setAddingFriend] = useState(false); - const query = useQuery({ + // Real, live-confirmed bug (2026-09-25 review): `GET /users/{id}/profile` 400s on a SELF lookup, + // same self-lookup gap already documented and fixed elsewhere for the group-scoped equivalent + // (getMyGroupProfile's own comment, `lib/api/groups.ts`) -- tapping your OWN avatar (reachable from + // the member grid/list like anyone else's) always landed on the "加载失败,请重试" branch, retrying + // into the same 400 forever. Routes self through the dedicated `GET /me/profile` instead, which has + // no such restriction; normalized into the same shape the render below already expects so the two + // branches don't need two separate JSX trees. + const otherQuery = useQuery({ queryKey: ['user-profile', userId], queryFn: () => getUserProfile(userId), + enabled: !isSelf, }); - const profile = query.data; + const selfQuery = useQuery({ + queryKey: ['my-profile-card', userId], + queryFn: () => getMyProfile(), + enabled: isSelf, + }); + const query = isSelf ? selfQuery : otherQuery; + const profile = isSelf + ? selfQuery.data + ? { + user_id: userId, + display_name: selfQuery.data.nickname, + avatar_file_id: selfQuery.data.avatar_file_id, + gender: selfQuery.data.gender, + region: selfQuery.data.region, + signature: selfQuery.data.signature, + public_account: selfQuery.data.public_account, + relationship: 'self', + remark: undefined as string | undefined, + capabilities: undefined as { can_send?: boolean; can_call?: boolean; can_add_friend?: boolean } | undefined, + } + : undefined + : otherQuery.data; const name = profile ? profile.remark || profile.display_name : ''; // Real bug this fixes: this card's own doc comment always claimed "same relationship-aware action // gating" as FriendProfileView.tsx, but until now it never read `profile.relationship` at all --