gaoluyang
6 小时以前 787ccc59ba89bacc075562a161ecf02bc76ebadc
src/views/im/home/store/channelStore.ts
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,108 @@
import type { ImManagerChannelApi } from '#/api/im/manager/channel'
import { acceptHMRUpdate, defineStore } from 'pinia'
import { getSimpleChannelList } from '#/api/im/manager/channel'
import { ImConversationType } from '../../utils/constants'
import { getDb } from '../../utils/db'
import { useConversationStore } from './conversationStore'
/**
 * IM é¢‘道 Store
 *
 * è´Ÿè´£ï¼šç¼“存当前用户能看到的频道精简列表(含 id / code / name / avatar),
 * ä¾›ä¼šè¯åˆ—表 / å¡ç‰‡æ¸²æŸ“时反查频道名称 + å¤´åƒï¼Œé¿å…æ˜¾ç¤ºã€Œé¢‘道 1」这种占位
 */
export const useChannelStore = defineStore('imChannelStore', {
  state: () => ({
    channels: [] as ImManagerChannelApi.Channel[],
    loaded: false
  }),
  getters: {
    getChannel(state): (id: number) => ImManagerChannelApi.Channel | undefined {
      return (id: number) => state.channels.find((c) => c.id === id)
    }
  },
  actions: {
    // ==================== æœ¬åœ°ç¼“å­˜ ====================
    /** ä»Ž IndexedDB æ¢å¤é¢‘道列表 */
    async loadChannelList(): Promise<boolean> {
      try {
        const cached = await getDb().getAll<ImManagerChannelApi.Channel>('channels')
        if (!cached || cached.length === 0) {
          return false
        }
        this.channels = cached
        return true
      } catch (error) {
        console.warn('[IM channelStore] æœ¬åœ°é¢‘道缓存读取失败', error)
        return false
      }
    },
    /** ä¿å­˜é¢‘道列表 */
    saveChannelList(): void {
      void getDb()
        .transaction(['channels'], 'readwrite', async (tx) => {
          const db = getDb()
          await db.clearStore('channels', tx)
          for (const channel of this.channels) {
            await db.put('channels', channel, tx)
          }
        })
        .catch((error) => console.warn('[IM channelStore] æœ¬åœ°é¢‘道缓存写入失败', error))
    },
    // ==================== è¿œç«¯æ‹‰å– ====================
    /** æ‹‰å–启用的频道精简列表;成功后回填会话列表已有的频道 name / avatar,覆盖 IDB æ—§å ä½ */
    async fetchChannelList(force = false) {
      if (this.loaded && !force) {
        return
      }
      try {
        this.channels = (await getSimpleChannelList()) || []
        this.loaded = true
        this.syncChannelConversationMetadata()
        this.saveChannelList()
      } catch (error) {
        console.warn('[IM channelStore] fetchChannelList å¤±è´¥', error)
      }
    },
    /** ç”¨æœ€æ–°çš„频道信息覆盖已有 CHANNEL ä¼šè¯çš„ name / avatar */
    syncChannelConversationMetadata() {
      const conversationStore = useConversationStore()
      const indexed = new Map(this.channels.map((c) => [c.id, c]))
      conversationStore.conversations.forEach((conversation) => {
        if (conversation.type !== ImConversationType.CHANNEL) {
          return
        }
        const channel = indexed.get(conversation.targetId)
        if (!channel) {
          return
        }
        conversationStore.updateConversation(ImConversationType.CHANNEL, conversation.targetId, {
          name: channel.name,
          avatar: channel.avatar
        })
      })
    },
    /** æ¸…空频道内存 */
    clear() {
      this.channels = []
      this.loaded = false
    }
  }
})
if (import.meta.hot) {
  import.meta.hot.accept(acceptHMRUpdate(useChannelStore, import.meta.hot))
}
export const useChannelStoreWithOut = () => useChannelStore()