From cb9cd49627b65a4c0e137e08063271a8cefe1826 Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期四, 23 七月 2026 17:48:49 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/dev_pro2.0' into dev_pro2.0
---
src/views/im/home/components/group/group-avatar.vue | 131 +++++++++++++++++++++++++++++++++++++++++++
1 files changed, 131 insertions(+), 0 deletions(-)
diff --git a/src/views/im/home/components/group/group-avatar.vue b/src/views/im/home/components/group/group-avatar.vue
new file mode 100644
index 0000000..021714f
--- /dev/null
+++ b/src/views/im/home/components/group/group-avatar.vue
@@ -0,0 +1,131 @@
+<script lang="ts" setup>
+import type { GroupMember } from '../../types'
+
+import { computed, ref, watch } from 'vue'
+
+import {
+ buildGroupAvatar,
+ getCachedGroupAvatar,
+ setCachedGroupAvatar
+} from '../../../utils/group'
+import { getMemberDisplayName } from '../../../utils/user'
+import { useFriendStore } from '../../store/friendStore'
+import { useGroupStore } from '../../store/groupStore'
+import { UserAvatar } from '../user'
+
+defineOptions({ name: 'ImGroupAvatar' })
+
+const props = withDefaults(
+ defineProps<{
+ clickable?: boolean // 鏄惁鍙偣鍑伙紙榛樿 false锛屽垪琛ㄩ噷浠呭睍绀猴級
+ groupId: number // 缇ょ紪鍙凤紱鐢ㄤ簬鏌� store 鎷挎垚鍛樺ご鍍�
+ name?: string // 缇ゅ悕锛涜壊鍗″厹搴曟枃瀛�
+ previewable?: boolean // 鏄惁鐐瑰ご鍍忕洿鎺ユ斁澶ч瑙堬紙缇よ鎯呭ぇ澶村儚浣嶇敤锛�
+ previewZIndex?: number // 棰勮灞� z-index
+ radius?: string // 鍦嗚锛孋SS 闀垮害
+ size?: number // 灏哄锛坧x锛夛紝姝f柟褰�
+ url?: string // 鏈嶅姟绔凡璁剧疆鐨勭兢澶村儚 URL锛涢潪绌哄垯鐩存帴鐢紝涓嶆嫾鍥�
+ }>(),
+ {
+ clickable: false,
+ name: '',
+ previewable: false,
+ previewZIndex: 2000,
+ radius: '15%',
+ size: 42,
+ url: ''
+ }
+)
+
+const friendStore = useFriendStore()
+const groupStore = useGroupStore()
+const mergedUrl = ref('')
+// 绔炴�佷繚鎶わ細涓㈠純杩囨湡 await 缁撴灉
+let mergeToken = 0
+
+/** 鎸夊鍣� size 脳 DPR 绠� canvas 瀹為檯鍍忕礌锛岄伩鍏� 2x / 3x retina 灞忔嫾鍥剧硦锛汥PR 灏侀《 3 闃叉瓒呴珮鍒嗚鲸鐜囩敾甯冭繃澶� */
+function getTargetSize(size: number): number {
+ const dpr = Math.min(window.devicePixelRatio || 1, 3)
+ return Math.max(Math.round(size * dpr), 64)
+}
+
+/** store 閲屾暣缇ゆ垚鍛樻槸鍚︺�屽畬鏁村姞杞姐�嶈繃锛涘彧鍦ㄤ负 true 鏃舵墠鎷煎浘锛岄伩鍏嶅垪琛ㄥ満鏅壒閲忓彂鎺ュ彛 */
+const loadedMembers = computed<GroupMember[] | null>(() => {
+ const g = groupStore.getGroup(props.groupId)
+ if (!g?.membersLoaded || !g.members) {
+ return null
+ }
+ return g.members
+})
+
+/** 鍓� 9 涓垚鍛樼殑鎷煎浘鍏ュ弬锛沶ame 璧� getMemberDisplayName 鍙e緞锛堝ソ鍙嬪娉� > 缇ゆ樀绉� > 鐪熷疄鏄电О锛� */
+const memberItems = computed(() => {
+ const members = loadedMembers.value
+ if (!members) {
+ return []
+ }
+ return members.slice(0, 9).map((m) => ({
+ avatar: m.avatar || '',
+ name: getMemberDisplayName(m, friendStore.getFriend(m.userId))
+ }))
+})
+
+/** 鎴愬憳蹇収绛惧悕锛氭嫾 (avatar, name) 瀛楁锛屽師鍦颁慨鏀逛换涓�瀛楁閮戒細璁� watch 閲嶇畻 */
+const memberSignature = computed(() =>
+ memberItems.value.map((it) => `${it.avatar}#${it.name}`).join('|')
+)
+
+/** 璧� buildGroupAvatar 鎷煎浘骞跺啓鍥� mergedUrl锛沵ergeToken 鏍¢獙閬垮厤鑰� await 瑕嗙洊鏂扮粨鏋� */
+async function applyMerge(key: string, targetSize: number): Promise<void> {
+ const myToken = ++mergeToken
+ const cached = getCachedGroupAvatar(key)
+ if (cached) {
+ mergedUrl.value = cached
+ return
+ }
+ const dataUrl = await buildGroupAvatar(memberItems.value, { targetSize })
+ if (myToken !== mergeToken) {
+ return
+ }
+ if (dataUrl) {
+ setCachedGroupAvatar(key, dataUrl)
+ }
+ mergedUrl.value = dataUrl
+}
+
+watch(
+ () => [props.url, props.groupId, props.size, memberSignature.value] as const,
+ ([url, groupId, size, signature]) => {
+ if (url) {
+ mergedUrl.value = ''
+ return
+ }
+ if (!signature) {
+ mergeToken++
+ mergedUrl.value = ''
+ groupStore.loadGroupMemberList(groupId)
+ return
+ }
+ const targetSize = getTargetSize(size)
+ const key = `${groupId}:${targetSize}:${signature}`
+ applyMerge(key, targetSize)
+ },
+ { immediate: true }
+)
+
+/** 鏈�缁堝睍绀� url锛氭湇鍔$ url 浼樺厛 鈫� 鎷煎浘 鈫� 绌哄瓧绗︿覆锛堣 UserAvatar 璧拌壊鍗★級 */
+const finalUrl = computed(() => props.url || mergedUrl.value)
+</script>
+
+<template>
+ <!-- url 闈炵┖璧板師鍥撅紱url 绌烘椂鍙栧墠 9 涓垚鍛樺ご鍍忔嫾涔濆鏍� dataURL锛屾垚鍛樻湭鍦� store 缂撳瓨鏃惰蛋鑹插崱鍏滃簳 -->
+ <UserAvatar
+ :url="finalUrl"
+ :name="name"
+ :size="size"
+ :radius="radius"
+ :clickable="clickable"
+ :previewable="previewable"
+ :preview-z-index="previewZIndex"
+ />
+</template>
--
Gitblit v1.9.3