diff --git a/src/api/im/group/index.ts b/src/api/im/group/index.ts
index 5d76639d8..d9b2f1f94 100644
--- a/src/api/im/group/index.ts
+++ b/src/api/im/group/index.ts
@@ -17,6 +17,8 @@ export interface ImGroupRespVO {
createTime?: string // 创建时间
pinnedMessages?: ImGroupMessageRespVO[] // 群置顶消息列表(后端关联回填,仅当登录用户是群成员时非空)
joinStatus?: number // 当前登录用户在该群的成员状态(参见 CommonStatusEnum:0 在群 / 1 已退群);历史退群群仍返回,供展示离线消息的群名 / 头像
+ groupRemark?: string // 当前登录用户对该群的备注
+ silent?: boolean // 当前登录用户是否免打扰
}
// 群消息置顶 / 取消置顶 Request VO
diff --git a/src/views/im/home/components/user/RecommendCardDialog.vue b/src/views/im/home/components/user/RecommendCardDialog.vue
index 95a5ef24b..a2ce6645b 100644
--- a/src/views/im/home/components/user/RecommendCardDialog.vue
+++ b/src/views/im/home/components/user/RecommendCardDialog.vue
@@ -119,7 +119,7 @@ import { ImConversationType, ImContentType, isGroupConversation } from '../../..
import { getConversationKey } from '../../../utils/conversation'
import { buildDefaultGroupName } from '../../../utils/group'
import { serializeMessage, type CardTarget } from '../../../utils/message'
-import { isGroupQuit } from '../../../utils/user'
+import { getGroupDisplayName, isGroupQuit } from '../../../utils/user'
import type { Conversation, FriendLite } from '../../types'
defineOptions({ name: 'ImRecommendCardDialog' })
@@ -283,7 +283,7 @@ async function handleCreateGroupAndSend() {
const newConversation: Conversation = {
type: ImConversationType.GROUP,
targetId: group.id,
- name: group.name || name,
+ name: getGroupDisplayName(group) || name,
avatar: group.avatar || '',
unreadCount: 0,
lastContent: '',
diff --git a/src/views/im/home/composables/useMessagePuller.ts b/src/views/im/home/composables/useMessagePuller.ts
index dbb8c55da..74a41b41b 100644
--- a/src/views/im/home/composables/useMessagePuller.ts
+++ b/src/views/im/home/composables/useMessagePuller.ts
@@ -3,7 +3,7 @@ import { useConversationStore } from '../store/conversationStore'
import { useMessageStore, type PulledMessage } from '../store/messageStore'
import { useImWebSocketStore } from '../store/websocketStore'
import { useFriendStore } from '../store/friendStore'
-import { getFriendDisplayName } from '../../utils/user'
+import { getFriendDisplayName, getGroupDisplayName } from '../../utils/user'
import { useGroupStore } from '../store/groupStore'
import { useGroupRequestStore } from '../store/groupRequestStore'
import {
@@ -149,7 +149,7 @@ export const useMessagePuller = () => {
return {
type: ImConversationType.GROUP,
targetId: message.groupId,
- name: group?.name || String(message.groupId),
+ name: group ? getGroupDisplayName(group) : String(message.groupId),
avatar: group?.avatar || '',
silent: group?.silent
}
diff --git a/src/views/im/home/pages/conversation/components/conversation/ConversationPrivateSide.vue b/src/views/im/home/pages/conversation/components/conversation/ConversationPrivateSide.vue
index 2d1577e51..e85b43e58 100644
--- a/src/views/im/home/pages/conversation/components/conversation/ConversationPrivateSide.vue
+++ b/src/views/im/home/pages/conversation/components/conversation/ConversationPrivateSide.vue
@@ -85,9 +85,9 @@
/>
取消
- 保存
+
+ 保存
+
@@ -141,7 +141,7 @@ import { useMessage } from '@/hooks/web/useMessage'
import { useConversationStore } from '@/views/im/home/store/conversationStore'
import { useFriendStore } from '@/views/im/home/store/friendStore'
import { useGroupStore } from '@/views/im/home/store/groupStore'
-import { getFriendDisplayName } from '@/views/im/utils/user'
+import { getFriendDisplayName, getGroupDisplayName } from '@/views/im/utils/user'
import { ImConversationType } from '@/views/im/utils/constants'
import type { Conversation, Friend } from '../../../../types'
@@ -248,7 +248,7 @@ function handleGroupCreated(groupId: number) {
conversationStore.openConversation(
groupId,
ImConversationType.GROUP,
- group.name,
+ getGroupDisplayName(group),
group.avatar || '',
{ silent: !!group.silent }
)
diff --git a/src/views/im/home/pages/conversation/components/message/MessagePanel.vue b/src/views/im/home/pages/conversation/components/message/MessagePanel.vue
index 61224a6ba..3ba0836bf 100644
--- a/src/views/im/home/pages/conversation/components/message/MessagePanel.vue
+++ b/src/views/im/home/pages/conversation/components/message/MessagePanel.vue
@@ -260,6 +260,7 @@ import { ImRtcCallMediaType, ImRtcCallStatus, ImConversationType } from '@/views
import { resolveCallEndReasonText } from '@/views/im/utils/message'
import { getClientConversationId } from '@/views/im/utils/db'
import { getCurrentUserId } from '@/utils/auth'
+import { getGroupDisplayName } from '@/views/im/utils/user'
import { useRtcStore } from '../../../../store/rtcStore'
import { useMessageStore } from '../../../../store/messageStore'
@@ -405,10 +406,11 @@ const groupInfo = computed<
}
const group = groupStore.getGroup(conversation.targetId)
const selfMember = group?.members?.find((member) => member.userId === getCurrentUserId())
+ const showGroupName = group ? getGroupDisplayName(group) : conversation.name
return {
id: conversation.targetId,
name: group?.name || conversation.name,
- showGroupName: group?.name || conversation.name,
+ showGroupName,
showImage: group?.avatar || conversation.avatar,
notice: group?.notice,
remarkNickName: selfMember?.displayUserName,
diff --git a/src/views/im/home/pages/conversation/components/message/forward/MessageForwardDialog.vue b/src/views/im/home/pages/conversation/components/message/forward/MessageForwardDialog.vue
index 440473768..7e5f2fc65 100644
--- a/src/views/im/home/pages/conversation/components/message/forward/MessageForwardDialog.vue
+++ b/src/views/im/home/pages/conversation/components/message/forward/MessageForwardDialog.vue
@@ -154,7 +154,7 @@ import FacePicker from '../../input/FacePicker.vue'
import { useConversationStore } from '@/views/im/home/store/conversationStore'
import { useFriendStore } from '@/views/im/home/store/friendStore'
import { useGroupStore } from '@/views/im/home/store/groupStore'
-import { isGroupQuit } from '@/views/im/utils/user'
+import { getGroupDisplayName, isGroupQuit } from '@/views/im/utils/user'
import { useMessageSender } from '@/views/im/home/composables/useMessageSender'
import { useMessageMultiSelect } from '@/views/im/home/composables/useMessageMultiSelect'
import {
@@ -406,7 +406,7 @@ async function handleCreateGroupAndSend() {
const newConversation: Conversation = {
type: ImConversationType.GROUP,
targetId: group.id,
- name: group.name || name,
+ name: getGroupDisplayName(group) || name,
avatar: group.avatar || '',
unreadCount: 0,
lastContent: '',
diff --git a/src/views/im/home/pages/conversation/index.vue b/src/views/im/home/pages/conversation/index.vue
index 623a92716..b0edc825a 100644
--- a/src/views/im/home/pages/conversation/index.vue
+++ b/src/views/im/home/pages/conversation/index.vue
@@ -104,6 +104,7 @@ import { useImUiStore } from '../../store/uiStore'
import { ImConversationType } from '../../../utils/constants'
import { StorageKeys } from '../../../utils/db'
import { filterConversationsByKeyword, getConversationKey } from '../../../utils/conversation'
+import { getGroupDisplayName } from '../../../utils/user'
import type { Conversation } from '../../types'
import ResizableAside from '../../components/ResizableAside.vue'
import ConversationItem from './components/conversation/ConversationItem.vue'
@@ -220,7 +221,7 @@ function handleGroupCreated(groupId: number) {
conversationStore.openConversation(
groupId,
ImConversationType.GROUP,
- group.name,
+ getGroupDisplayName(group),
group.avatar || '',
{ silent: !!group.silent }
)
diff --git a/src/views/im/home/store/groupStore.ts b/src/views/im/home/store/groupStore.ts
index 4b131f60c..c535ac769 100644
--- a/src/views/im/home/store/groupStore.ts
+++ b/src/views/im/home/store/groupStore.ts
@@ -227,7 +227,7 @@ export const useGroupStore = defineStore('imGroupStore', {
return
}
const fresh = (list || []).map((group) => convertGroup(group))
- // 合并而非全量替换:silent / groupRemark / 成员缓存这些字段不在 ImGroupRespVO 里,得从旧 group 保留
+ // 合并而非全量替换:成员缓存只在成员列表接口维护,群个人设置以群列表接口为准
const groupMap = new Map(this.groups.map((group) => [group.id, group]))
this.groups = fresh.map((group) => {
const existing = groupMap.get(group.id)
@@ -238,8 +238,6 @@ export const useGroupStore = defineStore('imGroupStore', {
...group,
members: existing.members,
memberCount: existing.memberCount ?? group.memberCount,
- silent: existing.silent ?? group.silent,
- groupRemark: existing.groupRemark,
membersLoaded: existing.membersLoaded,
membersExpired: existing.membersExpired
}
@@ -254,6 +252,24 @@ export const useGroupStore = defineStore('imGroupStore', {
})
}
this.saveGroupList()
+ this.preloadMembersForEmptyAvatarGroups()
+ },
+
+ /** 预加载空群头像的成员列表,供 GroupAvatar 异步合成群头像 */
+ preloadMembersForEmptyAvatarGroups() {
+ for (const group of this.groups) {
+ if (
+ group.avatar ||
+ group.joinStatus === CommonStatusEnum.DISABLE ||
+ (group.membersLoaded && !group.membersExpired && group.members?.length)
+ ) {
+ continue
+ }
+ const force = !!group.membersLoaded && !group.membersExpired && !group.members?.length
+ this.fetchGroupMemberList(group.id, force).catch((error) => {
+ console.warn('[IM groupStore] 预加载群头像成员失败', { groupId: group.id }, error)
+ })
+ }
},
/** 失效全部群成员缓存 */
@@ -892,7 +908,9 @@ function convertGroup(group: ImGroupRespVO): Group {
mutedAll: group.mutedAll,
banned: group.banned,
joinApproval: group.joinApproval,
- joinStatus: group.joinStatus
+ joinStatus: group.joinStatus,
+ groupRemark: group.groupRemark,
+ silent: group.silent
}
}
diff --git a/src/views/im/home/store/websocketStore.ts b/src/views/im/home/store/websocketStore.ts
index 3bf68edb8..012ca3a09 100644
--- a/src/views/im/home/store/websocketStore.ts
+++ b/src/views/im/home/store/websocketStore.ts
@@ -30,7 +30,7 @@ import {
import { useConversationStore } from './conversationStore'
import { useMessageStore } from './messageStore'
import { useFriendStore, type FriendNotificationPayload } from './friendStore'
-import { getFriendDisplayName } from '../../utils/user'
+import { getFriendDisplayName, getGroupDisplayName } from '../../utils/user'
import { useGroupStore } from './groupStore'
import { useGroupRequestStore } from './groupRequestStore'
import {
@@ -732,7 +732,7 @@ export const useImWebSocketStore = defineStore('imWebSocketStore', {
{
type: ImConversationType.GROUP,
targetId: websocketMessage.groupId,
- name: group?.name || String(websocketMessage.groupId),
+ name: group ? getGroupDisplayName(group) : String(websocketMessage.groupId),
avatar: group?.avatar || '',
silent: group?.silent
},