ForcePilot/web/src/stores/chatThreads.js

177 lines
5.1 KiB
JavaScript
Raw Normal View History

import { computed, ref } from 'vue'
import { defineStore } from 'pinia'
import { threadApi } from '@/apis'
import { handleChatError } from '@/utils/errorHandler'
const PAGE_SIZE = 100
export const useChatThreadsStore = defineStore('chatThreads', () => {
const threads = ref([])
const currentThreadId = ref(null)
const hasMoreThreads = ref(true)
const isLoadingThreads = ref(false)
const isLoadingMoreThreads = ref(false)
const isCreatingThread = ref(false)
const isDeletingThread = ref(false)
const isRenamingThread = ref(false)
const currentThread = computed(() => {
if (!currentThreadId.value) return null
return threads.value.find((thread) => thread.id === currentThreadId.value) || null
})
const setCurrentThreadId = (threadId) => {
currentThreadId.value = threadId || null
}
const clearThreads = () => {
threads.value = []
currentThreadId.value = null
hasMoreThreads.value = true
}
const loadThreads = async (agentId = null) => {
isLoadingThreads.value = true
try {
const fetchedThreads = await threadApi.getThreads(agentId, PAGE_SIZE, 0)
threads.value = fetchedThreads || []
hasMoreThreads.value = Boolean(fetchedThreads && fetchedThreads.length >= PAGE_SIZE)
if (
currentThreadId.value &&
!threads.value.find((thread) => thread.id === currentThreadId.value)
) {
currentThreadId.value = null
}
return threads.value
} catch (error) {
console.error('Failed to fetch threads:', error)
handleChatError(error, 'fetch')
throw error
} finally {
isLoadingThreads.value = false
}
}
const loadMoreThreads = async (agentId = null) => {
if (isLoadingMoreThreads.value || !hasMoreThreads.value) return
isLoadingMoreThreads.value = true
try {
const fetchedThreads = await threadApi.getThreads(agentId, PAGE_SIZE, threads.value.length)
if (fetchedThreads && fetchedThreads.length > 0) {
// 后端分页会重复返回置顶项,这里只追加列表中尚不存在的线程。
const existingIds = new Set(threads.value.map((thread) => thread.id))
const newThreads = fetchedThreads.filter((thread) => !existingIds.has(thread.id))
threads.value = [...threads.value, ...newThreads]
hasMoreThreads.value = newThreads.length >= PAGE_SIZE
} else {
hasMoreThreads.value = false
}
} catch (error) {
console.error('Failed to load more chats:', error)
handleChatError(error, 'fetch')
} finally {
isLoadingMoreThreads.value = false
}
}
const createThread = async (agentId, title = '新的对话') => {
if (!agentId) return null
isCreatingThread.value = true
try {
const thread = await threadApi.createThread(agentId, title)
if (thread) {
threads.value = [thread, ...threads.value.filter((item) => item.id !== thread.id)]
}
return thread
} catch (error) {
console.error('Failed to create thread:', error)
handleChatError(error, 'create')
throw error
} finally {
isCreatingThread.value = false
}
}
const deleteThread = async (threadId) => {
if (!threadId) return
isDeletingThread.value = true
try {
await threadApi.deleteThread(threadId)
threads.value = threads.value.filter((thread) => thread.id !== threadId)
if (currentThreadId.value === threadId) {
currentThreadId.value = null
}
} catch (error) {
console.error('Failed to delete thread:', error)
handleChatError(error, 'delete')
throw error
} finally {
isDeletingThread.value = false
}
}
const updateThread = async (threadId, title, isPinned) => {
if (!threadId) return
if (title) {
const normalizedTitle = String(title).replace(/\s+/g, ' ').trim().slice(0, 255)
if (!normalizedTitle) return
isRenamingThread.value = true
try {
await threadApi.updateThread(threadId, normalizedTitle, isPinned)
const thread = threads.value.find((item) => item.id === threadId)
if (thread) {
thread.title = normalizedTitle
if (isPinned !== undefined) {
thread.is_pinned = isPinned
}
}
} catch (error) {
console.error('Failed to update thread:', error)
handleChatError(error, 'update')
throw error
} finally {
isRenamingThread.value = false
}
return
}
if (isPinned !== undefined) {
try {
await threadApi.updateThread(threadId, null, isPinned)
const thread = threads.value.find((item) => item.id === threadId)
if (thread) {
thread.is_pinned = isPinned
}
} catch (error) {
console.error('Failed to update thread pin status:', error)
handleChatError(error, 'update')
throw error
}
}
}
return {
threads,
currentThreadId,
currentThread,
hasMoreThreads,
isLoadingThreads,
isLoadingMoreThreads,
isCreatingThread,
isDeletingThread,
isRenamingThread,
setCurrentThreadId,
clearThreads,
loadThreads,
loadMoreThreads,
createThread,
deleteThread,
updateThread
}
})