gaoluyang
2 天以前 b64a0deae5b5d33f9e20671a68936b27f0b9b00b
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
65
66
67
68
<script lang="ts" setup>
import { computed } from 'vue'
 
import { isPrivateConversation } from '#/views/im/utils/constants'
import {
  type CardMessage,
  type CardTarget,
  getCardLabelInfo
} from '#/views/im/utils/message'
 
import { UserAvatar } from '../user'
 
defineOptions({ name: 'ImCardBubble' })
 
const props = withDefaults(
  defineProps<{
    /** 名片数据;CardMessage(接收侧消息体)或 CardTarget(发送侧预览)共用结构 */
    card: CardMessage | CardTarget
    /** 是否显示 cursor: pointer;调用方负责绑 @click 监听 */
    clickable?: boolean
  }>(),
  { clickable: false }
)
 
/** 是否用户名片:决定 UserAvatar 是否带 id 触发 UserInfoCard */
const isUser = computed(() => isPrivateConversation(props.card.targetType))
/** 名片标签信息 */
const labelInfo = computed(() => getCardLabelInfo(props.card))
</script>
 
<template>
  <!--
    名片消息气泡 / 名片预览卡(240px):用户名片 + 群名片通用
    - 头像 + 名字 + 群成员数副标题(仅群名片)+ 底部分隔条「群名片 / 个人名片」
    - 用户名片把 :id 传给 UserAvatar 让点击 avatar 弹 UserInfoCard;群名片不传 id
    - 整卡 click 由调用方监听(@click),组件不内嵌业务逻辑
  -->
  <div
    class="flex flex-col w-[240px] rounded-md overflow-hidden bg-[var(--ant-color-bg-container)] border border-solid border-[var(--im-border-color-lighter)]"
    :class="{ 'cursor-pointer': clickable }"
  >
    <div class="flex gap-2.5 items-center px-3 py-2.5">
      <UserAvatar
        :id="isUser ? card.targetId : undefined"
        :url="card.avatar"
        :name="card.name"
        :size="40"
        :clickable="false"
      />
      <div class="flex flex-col flex-1 min-w-0">
        <div class="text-sm font-medium truncate text-[var(--ant-color-text)]">
          {{ card.name }}
        </div>
        <div
          v-if="!isUser && card.memberCount"
          class="text-12px truncate text-[var(--ant-color-text-placeholder)]"
        >
          {{ card.memberCount }} 人群聊
        </div>
      </div>
    </div>
    <div
      class="px-3 py-1 text-12px border-t border-t-solid text-[var(--ant-color-text-placeholder)] border-[var(--im-border-color-lighter)] bg-[var(--ant-color-fill-tertiary)]"
    >
      {{ labelInfo.label }}
    </div>
  </div>
</template>