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/store/uiStore.ts | 155 +++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 155 insertions(+), 0 deletions(-)
diff --git a/src/views/im/home/store/uiStore.ts b/src/views/im/home/store/uiStore.ts
new file mode 100644
index 0000000..93d0b6e
--- /dev/null
+++ b/src/views/im/home/store/uiStore.ts
@@ -0,0 +1,155 @@
+import type { GroupLite, User } from '../types'
+
+import { reactive, ref } from 'vue'
+
+import { acceptHMRUpdate, defineStore } from 'pinia'
+
+import { ImFriendAddSource } from '../../utils/constants'
+
+/**
+ * IM 鍏ㄥ眬 UI store
+ *
+ * 鏀剁撼鏍囧噯锛氳Е鍙戠偣 N 涓�佹寕杞界偣鎯充繚鎸� 1 涓殑娴眰鐘舵�併��
+ * 浠绘剰浣嶇疆閮藉彲鑳� open锛屼絾 DOM 涓婂彧鎯崇暀涓�浠藉疄渚� 鈫� 璧� store 娲惧彂锛�
+ * 鐢� `index.vue` 鎸備竴涓闃呯粍浠剁粺涓�娓叉煋銆�
+ */
+export const useImUiStore = defineStore('imUiStore', () => {
+ // ==================== 鐢ㄦ埛鍚嶇墖 UserInfoCard ====================
+ // 鐢ㄦ埛鍚嶇墖鎮诞鍗�
+
+ const userInfoCard = reactive({
+ show: false,
+ user: null as null | User,
+ position: { x: 0, y: 0 },
+ // addSource / addSourceExtra 璺熼殢瑙﹀彂鐐瑰甫鍏ャ�屽姞濂藉弸銆嶆潵婧愶紙缇ゆ垚鍛樺叆鍙� = GROUP + 缇ゅ悕锛涘叾浣欓粯璁ゆ悳绱級
+ addSource: ImFriendAddSource.SEARCH as number,
+ addSourceExtra: '' as string
+ })
+
+ /** 鎵撳紑鐢ㄦ埛鍚嶇墖 */
+ function openUserInfoCard(
+ user: User,
+ position: { x: number; y: number },
+ addSource: number = ImFriendAddSource.SEARCH,
+ addSourceExtra: string = ''
+ ) {
+ const viewportWidth = document.documentElement.clientWidth
+ const viewportHeight = document.documentElement.clientHeight
+ userInfoCard.user = user
+ userInfoCard.position.x = Math.min(position.x, viewportWidth - 350)
+ userInfoCard.position.y = Math.min(position.y, viewportHeight - 220)
+ userInfoCard.addSource = addSource
+ userInfoCard.addSourceExtra = addSourceExtra
+ userInfoCard.show = true
+ }
+
+ /** 榧犳爣鐐瑰嚮浣嶇疆 + 20px 妯悜鍋忕Щ鎵撳紑鍚嶇墖锛氶伩鍏嶅悕鐗囩洿鎺ヨ鐩栬Е鍙戝厓绱狅紝瀵归綈澶村儚 / 鍚嶇墖娑堟伅绛夌偣鍑讳氦浜掔殑缁熶竴瑙傛劅 */
+ function openUserInfoCardAtEvent(
+ user: User,
+ e: MouseEvent,
+ addSource: number = ImFriendAddSource.SEARCH,
+ addSourceExtra: string = ''
+ ) {
+ openUserInfoCard(user, { x: e.clientX + 20, y: e.clientY }, addSource, addSourceExtra)
+ }
+
+ /** 鍏抽棴鐢ㄦ埛鍚嶇墖 */
+ function closeUserInfoCard() {
+ userInfoCard.show = false
+ }
+
+ // ==================== 缇ゅ悕鐗� GroupInfoCard ====================
+
+ const groupInfoCard = reactive({
+ show: false,
+ group: null as GroupLite | null,
+ position: { x: 0, y: 0 }
+ })
+
+ /** 榧犳爣鐐瑰嚮浣嶇疆 + 20px 妯悜鍋忕Щ鎵撳紑缇ゅ悕鐗囷紝瀵归綈 UserInfoCard 鐨勭粺涓�瑙傛劅 */
+ function openGroupInfoCardAtEvent(group: GroupLite, e: MouseEvent) {
+ const viewportWidth = document.documentElement.clientWidth
+ const viewportHeight = document.documentElement.clientHeight
+ groupInfoCard.group = group
+ groupInfoCard.position.x = Math.min(e.clientX + 20, viewportWidth - 350)
+ groupInfoCard.position.y = Math.min(e.clientY, viewportHeight - 220)
+ groupInfoCard.show = true
+ }
+
+ /** 鍏抽棴缇ゅ悕鐗� */
+ function closeGroupInfoCard() {
+ groupInfoCard.show = false
+ }
+
+ // ==================== 鍙抽敭鑿滃崟 ContextMenu ====================
+ // 鍙抽敭鑿滃崟铏界劧鏄竴涓粍浠舵寕鍦ㄤ富澹充笂锛屼絾鍏惰Е鍙戞椂鏈哄垎鏁e湪鍚勫垪琛�
+ interface ContextMenuItem {
+ key: string
+ name: string
+ disabled?: boolean
+ divided?: boolean // 鏄惁鍦ㄨ椤逛笂鏂规樉绀哄垎鍓茬嚎锛堢敤浜庢妸"鍒犻櫎"绛夊嵄闄╂搷浣滀笌涓婇潰鐨勫父瑙勯」闅斿紑锛�
+ danger?: boolean // 鏄惁璧板嵄闄╂搷浣滄牱寮忥紙绾㈣壊鏂囧瓧锛�
+ icon?: string // 鍙�� iconify 鍥炬爣鍚嶏紙濡� ant-design:delete-outlined锛夛紱涓嶄紶鍒欎笉娓叉煋鍓嶇疆鍥炬爣
+ }
+
+ const contextMenu = reactive({
+ show: false,
+ position: { x: 0, y: 0 },
+ items: [] as ContextMenuItem[],
+ /** 閫変腑鍥炶皟锛氭瘡娆� open 鏃剁敱璋冪敤鏂逛紶鍏� */
+ onSelect: null as ((item: ContextMenuItem) => void) | null
+ })
+
+ /** 鎵撳紑鍙抽敭鑿滃崟 */
+ function openContextMenu(
+ position: { x: number; y: number },
+ items: ContextMenuItem[],
+ onSelect: (item: ContextMenuItem) => void
+ ) {
+ contextMenu.position = position
+ contextMenu.items = items
+ contextMenu.onSelect = onSelect
+ contextMenu.show = true
+ }
+
+ /** 鍏抽棴鍙抽敭鑿滃崟 */
+ function closeContextMenu() {
+ contextMenu.show = false
+ contextMenu.onSelect = null
+ }
+
+ // ==================== 娑堟伅 Tab 璺宠浆涓嬩竴鏈 ====================
+ // 鍦� ImHomeConversation 椤甸潰鍐嶆鐐瑰嚮宸ュ叿鏍忋�屾秷鎭�嶆椂瑙﹀彂锛�
+ // 閫氳繃閫掑 nonce 璁� conversation/index.vue 鐨� watch 鎰熺煡鍚庢墽琛屾粴鍔� + 楂樹寒
+
+ const nextUnreadJumpNonce = ref(0)
+
+ /** 璇锋眰婊氬姩鍒颁笅涓�涓湭璇讳細璇濓紙鍚厤鎵撴壈锛� */
+ function requestNextUnreadJump() {
+ nextUnreadJumpNonce.value++
+ }
+
+ return {
+ userInfoCard,
+ openUserInfoCard,
+ openUserInfoCardAtEvent,
+ closeUserInfoCard,
+
+ groupInfoCard,
+ openGroupInfoCardAtEvent,
+ closeGroupInfoCard,
+
+ contextMenu,
+ openContextMenu,
+ closeContextMenu,
+
+ nextUnreadJumpNonce,
+ requestNextUnreadJump
+ }
+})
+
+// dev: 璁� Pinia 鐨� actions / state 鏀瑰姩鏀寔 HMR锛岄伩鍏嶆瘡娆℃敼 store 閮藉緱纭埛
+// 鍚﹀垯 Vite 鎶婃柊妯″潡鎺ㄤ笅鏉ュ悗锛岃�� store 瀹炰緥鐨� action 闂寘浠嶆寚鍚戞棫鍑芥暟浣�
+if (import.meta.hot) {
+ import.meta.hot.accept(acceptHMRUpdate(useImUiStore, import.meta.hot))
+}
--
Gitblit v1.9.3