From 27cd042df9aca0383a49f3514bc21958dd890912 Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期一, 29 六月 2026 15:42:23 +0800
Subject: [PATCH] 银川 1.联调产品维护页面 2.添加IM即时通讯模块
---
src/views/im/home/components/user/user-info-card.vue | 121 ++++++++++++++++++++++++++++++++++++++++
1 files changed, 121 insertions(+), 0 deletions(-)
diff --git a/src/views/im/home/components/user/user-info-card.vue b/src/views/im/home/components/user/user-info-card.vue
new file mode 100644
index 0000000..ec33489
--- /dev/null
+++ b/src/views/im/home/components/user/user-info-card.vue
@@ -0,0 +1,121 @@
+<script lang="ts" setup>
+import { computed, onMounted, onUnmounted } from 'vue'
+import { useRouter } from 'vue-router'
+
+import { getCurrentUserId } from '#/views/im/utils/auth'
+
+import { ImConversationType } from '../../../utils/constants'
+import { getFriendDisplayName } from '../../../utils/user'
+import { useConversationStore } from '../../store/conversationStore'
+import { useFriendStore } from '../../store/friendStore'
+import { useImUiStore } from '../../store/uiStore'
+import UserInfo, { type UserInfoRelation } from './user-info.vue'
+
+defineOptions({ name: 'ImUserInfoCard' })
+
+const uiStore = useImUiStore()
+const conversationStore = useConversationStore()
+const friendStore = useFriendStore()
+const router = useRouter()
+
+const card = computed(() => uiStore.userInfoCard)
+const user = computed(() => card.value.user)
+
+const isSelf = computed(() => {
+ const myId = getCurrentUserId()
+ return !!user.value?.id && user.value.id === myId
+})
+const isActiveFriend = computed(() => {
+ if (!user.value?.id || isSelf.value) {
+ return false
+ }
+ return friendStore.isActiveFriend(user.value.id)
+})
+const relation = computed<UserInfoRelation>(() => {
+ if (!user.value) {
+ return 'readonly'
+ }
+ if (isSelf.value) {
+ return 'self'
+ }
+ if (isActiveFriend.value) {
+ return 'friend'
+ }
+ return 'stranger'
+})
+
+const remark = computed(() => {
+ if (!isActiveFriend.value || !user.value?.id) {
+ return undefined
+ }
+ return friendStore.getFriend(user.value.id)?.displayName || ''
+})
+
+/** 鍏抽棴鍚嶇墖锛氱偣鍑婚伄缃� / Esc / UserInfo 鎶涗笂鏉ョ殑鍒犻櫎鎴愬姛浜嬩欢 */
+function handleClose() {
+ uiStore.closeUserInfoCard()
+}
+
+/** 閿洏浜嬩欢锛欵sc 閿叧闂悕鐗� */
+function handleKeydown(e: KeyboardEvent) {
+ if (e.key === 'Escape' && card.value.show) {
+ handleClose()
+ }
+}
+
+onMounted(() => window.addEventListener('keydown', handleKeydown))
+onUnmounted(() => window.removeEventListener('keydown', handleKeydown))
+
+/** 鍙戞秷鎭細UserInfo 鎶涗笂鏉ョ殑"鍙戞秷鎭�"锛岀敱鏈粍浠舵帴鍔涘仛 openConversation + 璺虫秷鎭� Tab + 鍏虫诞灞� */
+function handleSendMessage() {
+ if (!user.value) {
+ return
+ }
+ // 鍙� friendStore 閲岀殑鏈�鏂板娉� / 鍏嶆墦鎵帮紝閬垮厤鏂板缓浼氳瘽鐢ㄨ繃鏈熸暟鎹�
+ const friend = friendStore.getFriend(user.value.id)
+ const conversationName = friend
+ ? getFriendDisplayName(friend)
+ : user.value.nickname || ''
+ conversationStore.openConversation(
+ user.value.id,
+ ImConversationType.PRIVATE,
+ conversationName,
+ user.value.avatar || '',
+ { silent: !!friend?.silent }
+ )
+ // 璺宠浆浼氳瘽 Tab锛堝鏋滀笉鍦ㄧ殑璇濓級锛屽苟涓斾笉绠″綋鍓嶈矾鐢辨槸鍟ラ兘鍏堝垏鍒颁細璇濆垪琛ㄩ〉
+ if (router.currentRoute.value.name !== 'ImHomeConversation') {
+ router.push({ name: 'ImHomeConversation' })
+ }
+ uiStore.closeUserInfoCard()
+}
+</script>
+
+<template>
+ <!--
+ 鐢ㄦ埛鍚嶇墖娴眰
+ - 浠呮壙鎷�"娴眰瀹氫綅 + 鍏抽棴閫昏緫锛堢偣閬僵 / Esc锛�"锛屽悕鐗囪瑙夎蛋 <UserInfo>锛屼笌 contact 璇︽儏鍏辩敤涓�浠界粍浠�
+ - 瑙﹀彂锛歶seImUiStore.openUserInfoCard(user, position)锛涙湰缁勪欢璁㈤槄 store锛屽叏灞�鍙寕涓�浠藉疄渚�
+ - 鍏崇郴鎬佺敱 isSelf / isActiveFriend 娲剧敓 relation prop 閫忓埌 UserInfo锛涘垹闄� / 鍔犲ソ鍙� / 澶囨敞钀藉簱閮藉湪 UserInfo 鍐呴棴鐜�
+ -->
+ <teleport to="body">
+ <div v-if="card.show" class="fixed inset-0 z-9998" @click.self="handleClose">
+ <div
+ class="fixed w-80 p-4 bg-[var(--ant-color-bg-elevated)] rounded-md shadow-xl"
+ :style="{ left: `${card.position.x }px`, top: `${card.position.y }px` }"
+ @click.stop
+ >
+ <UserInfo
+ :user="user"
+ :display-name="remark"
+ :relation="relation"
+ :preview-z-index="10000"
+ :add-source="card.addSource"
+ :add-source-extra="card.addSourceExtra"
+ @chat="handleSendMessage"
+ @deleted="handleClose"
+ />
+ </div>
+ </div>
+ </teleport>
+</template>
--
Gitblit v1.9.3