import { defineStore } from 'pinia' import { ServeGetTalkList, ServeCreateTalkList } from '@/api/chat' import { formatTalkItem, ttime, KEY_INDEX_NAME } from '@/utils/talk' import { useEditorDraftStore } from './editor-draft' import { ISession } from '@/types/chat' import { getConversations, addOrUpdateConversation, deleteConversation, getConversation } from '@/utils/db' interface TalkStoreState { loadStatus: number items: ISession[] } export const useTalkStore = defineStore('talk', { state: (): TalkStoreState => { return { // 加载状态[1:未加载;2:加载中;3:加载完成;4:加载失败;] loadStatus: 2, // 会话列表 items: [] } }, getters: { // 过滤所有置顶对话列表 topItems: (state) => { return state.items.filter((item: ISession) => item.is_top == 1) }, // 对话列表 talkItems: (state) => { return state.items.sort((a, b) => { return ttime(b.updated_at) - ttime(a.updated_at) }) }, // 消息未读数总计 talkUnreadNum: (state) => { return state.items.reduce((total: number, item: ISession) => { return total + item.unread_num }, 0) } }, actions: { findItem(index_name: string) { return this.items.find((item: ISession) => item.index_name === index_name) as ISession }, // 更新对话节点 async updateItem(params: any) { const item = this.items.find((item) => item.index_name === params.index_name) if (item) { Object.assign(item, params) // 同步更新本地数据库 try { await addOrUpdateConversation(JSON.parse(JSON.stringify(item))) } catch (error) { console.error('更新本地会话失败:', error) } } }, // 新增对话节点 async addItem(params: any) { this.items = [params, ...this.items] // 同步添加到本地数据库 try { await addOrUpdateConversation(JSON.parse(JSON.stringify(params))) } catch (error) { console.error('添加本地会话失败:', error) } }, // 移除对话节点 async delItem(index_name: string) { const i = this.items.findIndex((item) => item.index_name === index_name) if (i >= 0) { const item = this.items[i] this.items.splice(i, 1) // 同步从本地数据库删除 try { // 从本地数据库中查找并删除会话 const [talkType, receiverId] = index_name.split('_') const conversation = await getConversation(Number(talkType), Number(receiverId)) if (conversation && conversation.id) { await deleteConversation(conversation.id, false) // 不删除相关消息 } } catch (error) { console.error('删除本地会话失败:', error) } } this.items = [...this.items] }, // 更新对话消息 async updateMessage(params: any) { const item = this.items.find((item) => item.index_name === params.index_name) if (item) { item.unread_num++ item.msg_text = params.msg_text item.updated_at = params.updated_at // 同步更新本地数据库中的会话信息 try { await addOrUpdateConversation(JSON.parse(JSON.stringify(item))) } catch (error) { console.error('更新本地会话消息失败:', error) } } }, // 更新联系人备注 async setRemark(params: any) { const item = this.items.find((item) => item.index_name === `1_${params.user_id}`) if (item) { item.remark = params.remark // 同步更新本地数据库 try { await addOrUpdateConversation(JSON.parse(JSON.stringify(item))) } catch (error) { console.error('更新本地联系人备注失败:', error) } } }, // 加载会话列表 async loadTalkList() { this.loadStatus = 2 try { // 先从本地数据库加载会话列表 const localConversations = await getConversations() if (localConversations && localConversations.length > 0) { // 将本地会话列表转换为应用所需格式 this.items = localConversations.map((item: any) => { // 确保本地存储的会话格式与应用一致 const value = formatTalkItem(item) const draft = useEditorDraftStore().items[value.index_name] if (draft) { value.draft_text = JSON.parse(draft).text || '' } if (value.is_robot == 1) { value.is_online = 1 } return value }) // 设置为加载完成状态,因为已从本地加载了数据,不需要等待服务器数据就可以显示 this.loadStatus = 3 } // 从服务器获取最新会话列表 const resp = await ServeGetTalkList() if (resp.code == 200) { // 将服务器返回的会话列表转换为应用所需格式 const serverItems = resp.data.items.map((item: any) => { const value = formatTalkItem(item) const draft = useEditorDraftStore().items[value.index_name] if (draft) { value.draft_text = JSON.parse(draft).text || '' } if (value.is_robot == 1) { value.is_online = 1 } return value }) // 更新状态和本地数据库 this.items = serverItems console.log('serverItems',serverItems) // 将最新的会话列表保存到本地数据库 for (const item of serverItems) { await addOrUpdateConversation(item) } this.loadStatus = 3 } else { // 如果服务器请求失败但本地有数据,保持使用本地数据 if (this.items.length === 0) { this.loadStatus = 4 } else { this.loadStatus = 3 } } } catch (error) { console.error('加载会话列表失败:', error) // 如果有本地数据,即使服务器请求失败也显示本地数据 if (this.items.length === 0) { this.loadStatus = 4 } else { this.loadStatus = 3 } } }, findTalkIndex(index_name: string) { return this.items.findIndex((item: ISession) => item.index_name === index_name) }, async toTalk(talk_type: number, receiver_id: number, router: any) { const route = { path: '/message', query: { v: new Date().getTime() } } if (this.findTalkIndex(`${talk_type}_${receiver_id}`) >= 0) { sessionStorage.setItem(KEY_INDEX_NAME, `${talk_type}_${receiver_id}`) return router.push(route) } try { // 先检查本地数据库中是否有该会话 const localConversation = await getConversation(talk_type, receiver_id) if (localConversation) { // 如果本地有该会话,直接添加到列表中 if (this.findTalkIndex(`${talk_type}_${receiver_id}`) === -1) { this.addItem(formatTalkItem(localConversation)) } sessionStorage.setItem(KEY_INDEX_NAME, `${talk_type}_${receiver_id}`) return router.push(route) } // 如果本地没有,则从服务器创建 const { code, data, message } = await ServeCreateTalkList({ talk_type, receiver_id }) if (code == 200) { const formattedItem = formatTalkItem(data) if (this.findTalkIndex(`${talk_type}_${receiver_id}`) === -1) { await this.addItem(formattedItem) // 使用 await 确保本地数据库同步更新 } sessionStorage.setItem(KEY_INDEX_NAME, `${talk_type}_${receiver_id}`) return router.push(route) } else { window['$message'].info(message) } } catch (error) { console.error('创建会话失败:', error) window['$message'].error('创建会话失败,请稍后再试') } } } })