gaoluyang
2026-06-29 27cd042df9aca0383a49f3514bc21958dd890912
src/views/im/home/components/card/card-bubble.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,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>