267 lines
8.1 KiB
TypeScript
267 lines
8.1 KiB
TypeScript
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('创建会话失败,请稍后再试')
|
|
}
|
|
}
|
|
}
|
|
})
|