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

diff --git a/src/views/im/home/store/faceStore.ts b/src/views/im/home/store/faceStore.ts
new file mode 100644
index 0000000..8122443
--- /dev/null
+++ b/src/views/im/home/store/faceStore.ts
@@ -0,0 +1,151 @@
+import type { ImFacePackApi } from '#/api/im/face/pack'
+import type { ImFaceUserItemApi } from '#/api/im/face/userItem'
+
+import { ref } from 'vue'
+
+import { acceptHMRUpdate, defineStore } from 'pinia'
+
+import { getFacePackList as apiGetFacePackList } from '#/api/im/face/pack'
+import { createFaceUserItem as apiCreateFaceUserItem, deleteFaceUserItem as apiDeleteFaceUserItem, getFaceUserItemList as apiGetFaceUserItemList } from '#/api/im/face/userItem'
+
+/**
+ * IM 琛ㄦ儏闈㈡澘鏁版嵁 store锛堢郴缁熻〃鎯呭寘 + 涓汉琛ㄦ儏锛�
+ *
+ * 涓嶆寔涔呭寲锛氭暟鎹皬銆佷綆棰戯紱姣忔杩� IM 绗竴娆℃墦寮�琛ㄦ儏闈㈡澘鏃舵寜闇�鎷夛紝鍏� tab 鍗充涪寮�
+ * - 绯荤粺鍖咃細IM 涓婚〉 onMounted 鍚庡彴棰勬媺锛堜笉闃诲棣栧睆锛夛紝娑堥櫎闈㈡澘棣栨灞曞紑鐨勭櫧灞�
+ * - 涓汉琛ㄦ儏锛氬垏鍒般�屾敹钘忋�峵ab / 闀挎寜娑堟伅銆屾坊鍔犲埌琛ㄦ儏銆嶆椂鎸夐渶鎷�
+ */
+export const useFaceStore = defineStore('imFace', () => {
+
+  /** 绯荤粺琛ㄦ儏鍖呭垪琛紙鍚瘡涓寘鐨� items锛夛紱杩愯惀绠$悊鍚庡彴缁存姢 */
+  const facePacks = ref<ImFacePackApi.FacePackUser[]>([])
+  /** 涓汉琛ㄦ儏鍖呭垪琛紙鐢ㄦ埛闀挎寜銆屾坊鍔犲埌琛ㄦ儏銆�/ 涓婁紶浜х敓锛� */
+  const faceUserItems = ref<ImFaceUserItemApi.FaceUserItem[]>([])
+
+  /** clear() 鏃堕�掑锛涙棫璐﹀彿璇锋眰杩斿洖鍚庝笉鍐欏叆鏂拌处鍙峰唴瀛� */
+  let storeEpoch = 0
+
+  /**
+   * 绯荤粺琛ㄦ儏鍖呮媺鍙� promise锛沞nsureFacePackList 鍐� cache锛�
+   * - null = 杩樻病鎷夎繃锛屼笅娆¤皟鐢ㄧ湡鍙戣姹�
+   * - resolve 鍚庝繚鐣欏璞� = 鍚庣画璋冪敤 await 绔嬪嵆杩斿洖锛屼笉鍐嶅彂璇锋眰
+   * - reject 鍚庣疆鍥� null锛岃璋冪敤鏂逛笅娆¢噸璇�
+   */
+  let facePacksPromise: null | Promise<void> = null
+  /** 鎸夐渶鎷夊彇绯荤粺琛ㄦ儏鍖咃紙宸叉媺杩囧垯鐩存帴澶嶇敤 cached promise锛� */
+  async function ensureFacePackList(): Promise<void> {
+    if (!facePacksPromise) {
+      const requestEpoch = storeEpoch
+      facePacksPromise = apiGetFacePackList()
+        .then((data) => {
+          if (requestEpoch !== storeEpoch) {
+            return
+          }
+          facePacks.value = data || []
+        })
+        .catch((error) => {
+          console.warn('[IM] 鎷夊彇琛ㄦ儏鍖呭け璐�', error)
+          if (requestEpoch === storeEpoch) {
+            facePacksPromise = null
+          }
+          throw error
+        })
+    }
+    return facePacksPromise
+  }
+
+  /** 涓汉琛ㄦ儏鎷夊彇 promise锛涜涔夊悓涓� */
+  let faceUserItemsPromise: null | Promise<void> = null
+  /** 鎸夐渶鎷夊彇涓汉琛ㄦ儏锛堝凡鎷夎繃鍒欑洿鎺ュ鐢� cached promise锛� */
+  async function ensureFaceUserItemList(): Promise<void> {
+    if (!faceUserItemsPromise) {
+      const requestEpoch = storeEpoch
+      faceUserItemsPromise = apiGetFaceUserItemList()
+        .then((data) => {
+          if (requestEpoch !== storeEpoch) {
+            return
+          }
+          faceUserItems.value = data || []
+        })
+        .catch((error) => {
+          console.warn('[IM] 鎷夊彇涓汉琛ㄦ儏澶辫触', error)
+          if (requestEpoch === storeEpoch) {
+            faceUserItemsPromise = null
+          }
+          throw error
+        })
+    }
+    return faceUserItemsPromise
+  }
+
+  /**
+   * 娣诲姞涓汉琛ㄦ儏锛涙湇鍔$瀵瑰悓 URL 鎶� FACE_USER_ITEM_DUPLICATED 閿欒
+   *
+   * 鏉ユ簮锛�1. 鐢ㄦ埛鍦ㄨ〃鎯呴潰鏉裤��+銆嶄笂浼犲浘鐗�  2. 闀挎寜娑堟伅銆屾坊鍔犲埌琛ㄦ儏銆�
+   */
+  async function addFaceUserItem(reqVO: ImFaceUserItemApi.FaceUserItemSaveReqVO): Promise<boolean> {
+    const requestEpoch = storeEpoch
+    const id = await apiCreateFaceUserItem(reqVO)
+    if (!id) {
+      return false
+    }
+    // 宸插垏璐﹀彿鏃惰烦杩囨棫璇锋眰缁撴灉
+    if (requestEpoch !== storeEpoch) {
+      return false
+    }
+    // id 涓嶅湪缂撳瓨閲屾墠鎻掑叆锛涙湇鍔$鍞竴绾︽潫鍏滃簳浜� race锛屾湰鍦扮悊璁轰笂涓嶄細鎷垮埌閲嶅 id
+    if (!faceUserItems.value.some((item) => item.id === id)) {
+      faceUserItems.value.unshift({
+        id,
+        url: reqVO.url,
+        name: reqVO.name,
+        width: reqVO.width,
+        height: reqVO.height
+      })
+    }
+    return true
+  }
+
+  /** 鍒犻櫎涓汉琛ㄦ儏锛涙湰鍦扮珛鍗崇Щ闄� */
+  async function removeFaceUserItem(id: number): Promise<boolean> {
+    const requestEpoch = storeEpoch
+    try {
+      await apiDeleteFaceUserItem(id)
+      // 宸插垏璐﹀彿鏃惰烦杩囨棫璇锋眰缁撴灉
+      if (requestEpoch !== storeEpoch) {
+        return false
+      }
+      faceUserItems.value = faceUserItems.value.filter((item) => item.id !== id)
+      return true
+    } catch (error) {
+      console.warn('[IM] 鍒犻櫎涓汉琛ㄦ儏澶辫触', { id }, error)
+      return false
+    }
+  }
+
+  /** 娓呯┖琛ㄦ儏缂撳瓨 */
+  function clear(): void {
+    facePacks.value = []
+    faceUserItems.value = []
+    facePacksPromise = null
+    faceUserItemsPromise = null
+    storeEpoch++
+  }
+
+  return {
+    facePacks,
+    faceUserItems,
+    ensureFacePackList,
+    ensureFaceUserItemList,
+    addFaceUserItem,
+    removeFaceUserItem,
+    clear
+  }
+})
+
+/** 鍦� setup 澶栵紙璺敱瀹堝崼绛夛級鍙� store 瀹炰緥鐨勫伐鍏锋柟娉� */
+export const useFaceStoreWithOut = () => useFaceStore()
+
+if (import.meta.hot) {
+  import.meta.hot.accept(acceptHMRUpdate(useFaceStore, import.meta.hot))
+}

--
Gitblit v1.9.3