From 66dad284c75671e616c87083e098d04dc2e01732 Mon Sep 17 00:00:00 2001 From: Your Name Date: Wed, 16 Sep 2026 22:26:12 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E9=82=80=E8=AF=B7=E5=85=A5?= =?UTF-8?q?=E7=BE=A4=E4=BA=A4=E4=BA=92=EF=BC=9A=E7=82=B9=E5=87=BB=E9=82=80?= =?UTF-8?q?=E8=AF=B7=E8=A6=81=E7=9B=B4=E6=8E=A5=E8=BF=9B=E5=85=A5=E9=82=80?= =?UTF-8?q?=E8=AF=B7=EF=BC=8C=E8=80=8C=E4=B8=8D=E6=98=AF=E5=85=88=E7=9C=8B?= =?UTF-8?q?=E6=88=90=E5=91=98=E5=88=97=E8=A1=A8=E5=86=8D=E7=82=B9=E7=AC=AC?= =?UTF-8?q?=E4=BA=8C=E6=AC=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 用户实测反馈的真实bug:GroupDetailColumn里那个专门的"+邀请"图标(虚线边框 方块,只有canInvite为真才显示——这个权限门控本身一直是对的)点击后走的是 setOpenModal('members'),和"查看全部成员"是完全同一个入口——弹出的是成员 列表,标题栏里那个真正的"邀请"按钮还要再点一次才能看到可邀请的联系人列表。 GroupMembersModal新增initialView属性,"invite"直接以邀请视图打开(跳过 成员列表这一步),"查看全部"/"查看全部成员"两处不受影响仍然打开成员列表。 同时补全了邀请结果的反馈——原来邀请成功后只做了查询失效,无论是"立即加入" 还是需要对方/群设置审批的"待确认",界面上都没有任何区别于点击前的视觉反馈, 容易让人怀疑是不是点了没反应从而重复点击。读了im_be的serveIMGroupInvitations 源码(不是协议文档的单一示例)确认真实的单人邀请结果有joined/already_member/ pending/pending_approval/failed五种可能,现在每种都有对应的行内文案, "failed"不计入"已处理"状态,允许原地重试。 实机验证:全新建群后点"+邀请"直接进入邀请视图(标题"邀请成员",不经过成员 列表);邀请一个全新好友后确认成功加入、群成员数正确从2变3、界面正确显示 结果反馈。 Co-Authored-By: Claude Sonnet 5 --- web/src/features/groups/GroupDetailColumn.tsx | 19 ++++-- web/src/features/groups/GroupMembersModal.tsx | 61 ++++++++++++++++--- 2 files changed, 68 insertions(+), 12 deletions(-) diff --git a/web/src/features/groups/GroupDetailColumn.tsx b/web/src/features/groups/GroupDetailColumn.tsx index f2744bf1..4f77f137 100644 --- a/web/src/features/groups/GroupDetailColumn.tsx +++ b/web/src/features/groups/GroupDetailColumn.tsx @@ -81,7 +81,7 @@ export function GroupDetailColumn({ topicId, peerName, onClose, onOpenHistory }: const [nicknameEditing, setNicknameEditing] = useState(false); const [nicknameDraft, setNicknameDraft] = useState(''); const [errorToast, setErrorToast] = useState(''); - const [openModal, setOpenModal] = useState<'members' | 'announcement' | 'files' | 'admin' | 'qrcode' | null>(null); + const [openModal, setOpenModal] = useState<'members' | 'invite' | 'announcement' | 'files' | 'admin' | 'qrcode' | null>(null); const showError = (err: unknown, fallback: string) => setErrorToast(err instanceof Error ? err.message : fallback); // Same long-lived-instance leak this exact pattern already caused twice in DetailColumn.tsx -- @@ -284,7 +284,13 @@ export function GroupDetailColumn({ topicId, peerName, onClose, onOpenHistory }: ))} {canInvite ? ( -