gaoluyang
2026-06-29 27cd042df9aca0383a49f3514bc21958dd890912
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
<script lang="ts" setup>
import { computed } from 'vue'
 
import { ImFriendAddSource } from '../../../utils/constants'
import { UserAvatar } from '../user'
 
defineOptions({ name: 'ImGroupMember' })
 
const props = withDefaults(
  defineProps<{
    active?: boolean // 选中态(@候选键盘高亮等)
    clickable?: boolean // 头像点击是否弹 UserInfoCard;@候选场景通常禁用(避免嵌套交互)
    groupName?: string // 群名:加好友时拼「我是 'XX 群' 的 YY」话术,落库 add_source=GROUP
    height?: number // 行高(px),影响头像大小
    member: GroupMemberLite
  }>(),
  {
    height: 50,
    active: false,
    clickable: false,
    groupName: ''
  }
)
 
/** 群成员结构(跨多处使用,放这里做窄接口;独立于 types/index.ts) */
export interface GroupMemberLite {
  userId: number // 用户编号;特殊值见 IM_AT_ALL_USER_ID(@ 全体成员)
  nickname: string // 真实昵称:永远是用户的 nickname,专给 UserAvatar 色卡用,保证同一个人色卡首字母在所有界面一致
  showName: string // 展示昵称:好友备注 > 用户群备注(displayUserName) > 真实昵称(nickname),给"显示给用户看"的位置用(行内文字、@候选标签等)
  avatar?: string
  status?: number
  role?: number // 成员角色,仅在群信息抽屉等需要展示角色标签的场景透传;@候选 / 已读列表等场景可不传
}
 
const avatarSize = computed(() => Math.ceil(props.height * 0.75))
</script>
 
<template>
  <!--
    群成员单行
    跨子域复用:@候选 (MentionPicker) / 已读列表 (MessageReadStatus) / 群成员宫格 (ConversationGroupSide)
  -->
  <div
    class="relative flex items-center px-[5px] box-border whitespace-nowrap"
    :class="{ 'bg-[#e1eaf7] dark:bg-[var(--ant-color-primary-bg)]': active }"
    :style="{ height: `${height }px` }"
  >
    <UserAvatar
      :size="avatarSize"
      :name="member.nickname"
      :url="member.avatar"
      :clickable="clickable"
      :id="member.userId"
      :add-source="ImFriendAddSource.GROUP"
      :add-source-extra="groupName"
    />
    <div
      class="flex-1 h-full pl-2.5 overflow-hidden text-sm text-left truncate text-[var(--ant-color-text)]"
      :style="{ lineHeight: `${height }px` }"
    >
      {{ member.showName }}
    </div>
  </div>
</template>