From bfa267120ad98e2ff3e4a6172c8b827fad5815e2 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Mon, 27 Apr 2026 21:48:34 +0800 Subject: [PATCH] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor(im):=20MessageIte?= =?UTF-8?q?m=20=E5=A4=B4=E5=83=8F=E9=A1=B6=E5=8F=B3=20+=20MentionPicker/Me?= =?UTF-8?q?ssageInput=20=E5=91=BD=E5=90=8D=E6=B8=85=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 【MessageItem.vue】 - 头像合一:双 v-if 头像(左/右)收成单一 ,DOM 顺序固定为 [头像, 气泡],selfSend 靠外层 flex-row-reverse 翻视觉 → 头像顶右、气泡在 头像左侧。早先双 v-if + row-reverse 让自己消息时气泡顶右、头像反而被 挤在 bubble 左边,跟微信观感不对齐 - 5 处脚本 TODO 注释补齐:groupMembersForReadStatus / handleContextMenu / handleRecall / handleDelete,解释 WHY 而不是 WHAT - formatTipTime 局部变量按"不缩写"展开:d → messageDate / n → value / hm → hourMinute / (a,b) → (left,right) / weeks → weekNames - senderAvatar / groupMembersForReadStatus 回调参数 m → member、g → group 【MessageInput.vue】 - groupMembers producer 局部变量 g → group、(m) => → (member) => 【MentionPicker.vue】 - memberItems 过滤回调 (m) => → (member) => --- src/assets/audio/im-message-tip.mp3 | Bin 13059 -> 0 bytes .../components/input/MentionPicker.vue | 11 +- .../components/input/MessageInput.vue | 14 +- .../components/message/MessageItem.vue | 209 ++++++++++++------ src/views/im/manager/index.vue | 0 src/views/im/utils/index.ts | 30 --- 6 files changed, 157 insertions(+), 107 deletions(-) delete mode 100644 src/assets/audio/im-message-tip.mp3 delete mode 100644 src/views/im/manager/index.vue delete mode 100644 src/views/im/utils/index.ts diff --git a/src/assets/audio/im-message-tip.mp3 b/src/assets/audio/im-message-tip.mp3 deleted file mode 100644 index 5f317dcd466c5430bb0b7a7c1bee9ea8e3f6c430..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13059 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%0D#7~VnCN+4A3wP^3G94Y}5tr zb#cajtFme7R{byRPu%^jf@LD|+5@V!(R<+6P-@bA91EqfrH@R(c`?e}J*TLpG w*jxwy(() => { /** 真成员:过滤自己 / 退群 / 不匹配关键字;不截断数量,浮层 max-height + el-scrollbar 撑滚动 */ const memberItems = computed(() => props.members.filter( - (m) => - m.userId !== selfUserId.value && - !m.quit && - !!m.showNickName && - m.showNickName.startsWith(props.searchText) + (member) => + member.userId !== selfUserId.value && + member.status !== CommonStatusEnum.DISABLE && + !!member.showNickName && + member.showNickName.startsWith(props.searchText) ) ) diff --git a/src/views/im/home/pages/conversation/components/input/MessageInput.vue b/src/views/im/home/pages/conversation/components/input/MessageInput.vue index 52b443281..d8244609c 100644 --- a/src/views/im/home/pages/conversation/components/input/MessageInput.vue +++ b/src/views/im/home/pages/conversation/components/input/MessageInput.vue @@ -103,7 +103,6 @@ import { computed, onBeforeUnmount, onMounted, ref, useTemplateRef } from 'vue' import { ElMessage } from 'element-plus' import Icon from '@/components/Icon/src/Icon.vue' -import { CommonStatusEnum } from '@/utils/constants' import { updateFile } from '@/api/infra/file' import { useConversationStore } from '@/views/im/home/store/conversationStore' import { useGroupStore } from '@/views/im/home/store/groupStore' @@ -395,13 +394,12 @@ const groupMembers = computed(() => { if (!conversation || conversation.type !== ImConversationType.GROUP) { return [] } - // TODO @AI:g 变 group - const g = groupStore.getGroup(conversation.targetId) - return (g?.members || []).map((m) => ({ - userId: m.userId, - showNickName: m.displayUserName || m.nickname, - showImage: m.avatar, - quit: m.status === CommonStatusEnum.DISABLE + const group = groupStore.getGroup(conversation.targetId) + return (group?.members || []).map((member) => ({ + userId: member.userId, + showNickName: member.displayUserName || member.nickname, + showImage: member.avatar, + status: member.status })) }) diff --git a/src/views/im/home/pages/conversation/components/message/MessageItem.vue b/src/views/im/home/pages/conversation/components/message/MessageItem.vue index c446da669..d0269861d 100644 --- a/src/views/im/home/pages/conversation/components/message/MessageItem.vue +++ b/src/views/im/home/pages/conversation/components/message/MessageItem.vue @@ -1,8 +1,10 @@