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/composables/useFriendBuckets.ts |   99 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 99 insertions(+), 0 deletions(-)

diff --git a/src/views/im/home/composables/useFriendBuckets.ts b/src/views/im/home/composables/useFriendBuckets.ts
new file mode 100644
index 0000000..9b2ad1a
--- /dev/null
+++ b/src/views/im/home/composables/useFriendBuckets.ts
@@ -0,0 +1,99 @@
+import type { FriendLite } from '../types'
+
+import { computed, type ComputedRef, type Ref } from 'vue'
+
+/** 瀛楁瘝鍒嗘《缁撴灉锛歭etter 鍙� 'A'-'Z' 鎴栧厹搴� '#'锛沴ist 妗跺唴鎸夋嫾闊� / 鍚嶅瓧鑷劧搴� */
+export interface FriendBucket {
+  letter: string
+  list: FriendLite[]
+}
+
+/** 鍙栧垎妗� / 鎺掑簭閿細澶囨敞鎷奸煶浼樺厛 鈫� 鏄电О鎷奸煶 鈫� 鍚嶅瓧鏈韩锛堝厹搴曡嫳鏂� / 鏁板瓧锛� */
+function getSortKey(friend: FriendLite): string {
+  return (
+    friend.displayNamePinyin ||
+    friend.nicknamePinyin ||
+    (friend.displayName || friend.nickname || '').toLowerCase()
+  )
+}
+
+/** 鍙栧垎妗跺瓧姣嶏細鎷奸煶棣栧瓧姣嶅ぇ鍐欙紝闈炲瓧姣嶏紙绾鍙� / 鏁板瓧 / 涓枃锛夊厹搴� '#' */
+function getBucketLetter(friend: FriendLite): string {
+  const first = getSortKey(friend).charAt(0)
+  return /^[a-zA-Z]$/.test(first) ? first.toUpperCase() : '#'
+}
+
+/** 鎷奸煶棣栧瓧姣嶆嫾鎺ワ細銆宭ao zhang銆嶁啋 'lz'锛屾敮鎸併�岃緭 lz 鎼滆�佸紶銆� */
+function pinyinInitials(pinyin?: string): string {
+  if (!pinyin) {
+    return ''
+  }
+  return pinyin
+    .split(' ')
+    .map((word) => word.charAt(0))
+    .join('')
+}
+
+/**
+ * 濂藉弸鍒楄〃鐨勬悳绱� + 瀛楁瘝鍒嗘《
+ *
+ * - 鎼滅储鍖归厤锛氬娉� / 鏄电О / 鍏ㄦ嫾锛堝幓绌烘牸锛�/ 棣栧瓧姣嶄换涓�鍛戒腑
+ * - 鍒嗘《瑙勫垯锛欰-Z + '#' 鍏滃簳锛屾《鍐呮寜 getSortKey 鑷劧搴�
+ *
+ * 閫氳褰曢〉 FriendList 涓庨�夋嫨绫诲脊绐� FriendPickerPanel 鍏辩敤锛岄伩鍏嶈鍒欏悇鑷疄鐜拌蛋鍋�
+ */
+export function useFriendBuckets(
+  friends: ComputedRef<FriendLite[]> | Ref<FriendLite[]>,
+  keyword: Ref<string>
+): {
+  buckets: ComputedRef<FriendBucket[]>
+  filtered: ComputedRef<FriendLite[]>
+} {
+  const filtered = computed(() => {
+    const keywordLower = keyword.value.trim().toLowerCase()
+    if (!keywordLower) {
+      return friends.value
+    }
+    return friends.value.filter((friend) => {
+      const nicknamePinyin = friend.nicknamePinyin || ''
+      const displayNamePinyin = friend.displayNamePinyin || ''
+      // 鍏ㄦ嫾鎼滅储鍘绘帀绌烘牸锛岃銆宭aozhang銆嶄篃鑳藉懡涓�宭ao zhang銆�
+      return (
+        (friend.nickname || '').toLowerCase().includes(keywordLower) ||
+        (friend.displayName || '').toLowerCase().includes(keywordLower) ||
+        nicknamePinyin.replaceAll(/\s/g, '').includes(keywordLower) ||
+        displayNamePinyin.replaceAll(/\s/g, '').includes(keywordLower) ||
+        pinyinInitials(nicknamePinyin).includes(keywordLower) ||
+        pinyinInitials(displayNamePinyin).includes(keywordLower)
+      )
+    })
+  })
+
+  const buckets = computed<FriendBucket[]>(() => {
+    const map = new Map<string, FriendLite[]>()
+    for (const friend of filtered.value) {
+      const letter = getBucketLetter(friend)
+      const bucket = map.get(letter) ?? []
+      bucket.push(friend)
+      map.set(letter, bucket)
+    }
+    const letters = [...map.keys()].toSorted((a, b) => {
+      // '#' 姘歌繙鎺掓湯灏撅紝A-Z 璧� localeCompare
+      if (a === '#') {
+        return 1
+      }
+      if (b === '#') {
+        return -1
+      }
+      return a.localeCompare(b)
+    })
+    return letters.map((letter) => ({
+      letter,
+      list: (map.get(letter) ?? []).toSorted((a, b) =>
+        getSortKey(a).localeCompare(getSortKey(b))
+      )
+    }))
+  })
+
+  return { filtered, buckets }
+}

--
Gitblit v1.9.3