diff --git a/src/api/conversations.ts b/src/api/conversations.ts index bae5a19..11d3139 100644 --- a/src/api/conversations.ts +++ b/src/api/conversations.ts @@ -29,6 +29,10 @@ export function fetchConversation(id: number, offset = 0) { }); } +export function deleteConversation(id: number) { + return http.delete>(`/v1/conversations/${id}`); +} + export function sendConversationMessage( id: number, content: string, diff --git a/src/components/layout/AppSidebar.vue b/src/components/layout/AppSidebar.vue index 972cf6d..85d2817 100644 --- a/src/components/layout/AppSidebar.vue +++ b/src/components/layout/AppSidebar.vue @@ -95,6 +95,18 @@ async function openConversation(id: number) { } } +async function removeConversation(item: { id: number; title: string }) { + if (!window.confirm(`确定删除会话“${item.title}”吗?删除后无法恢复。`)) return; + try { + await conversationStore.remove(item.id); + if (conversationStore.current === null) { + await router.push({ name: "assessment", query: { new: String(Date.now()) } }); + } + } catch { + // The store exposes the request error. + } +} + function searchConversations() { void conversationStore.loadList(search.value.trim() || undefined); } @@ -131,14 +143,15 @@ function searchConversations() { - + +
@@ -264,6 +286,32 @@ section h2 { white-space: nowrap; } +.sidebar-item__delete { + display: none; + width: 22px; + height: 22px; + flex: 0 0 22px; + margin-left: auto; + border: 0; + border-radius: 6px; + background: transparent; + color: var(--color-text-faint); + font-size: 18px; + line-height: 1; + cursor: pointer; +} + +.sidebar-item:hover .sidebar-item__delete, +.sidebar-item:focus-within .sidebar-item__delete { + display: inline-grid; + place-items: center; +} + +.sidebar-item__delete:hover { + background: var(--color-danger-subtle); + color: var(--color-danger); +} + .risk-dot { width: 5px; height: 5px; diff --git a/src/stores/conversation.store.ts b/src/stores/conversation.store.ts index 6ea9b66..618937e 100644 --- a/src/stores/conversation.store.ts +++ b/src/stores/conversation.store.ts @@ -3,6 +3,7 @@ import { computed, reactive, ref } from "vue"; import { createConversation, + deleteConversation, fetchConversation, fetchConversations, withdrawConversationMessage, @@ -132,6 +133,16 @@ export const useConversationStore = defineStore("conversation", () => { return current.value; } + async function remove(id: number) { + const active = current.value?.id === id; + await deleteConversation(id); + streamStates.get(id)?.controller.abort(); + streamStates.delete(id); + conversationCache.delete(id); + items.value = items.value.filter((item) => item.id !== id); + if (active) current.value = null; + } + async function send( content: string, messageType: ConversationMessageType = "text", @@ -428,6 +439,7 @@ export const useConversationStore = defineStore("conversation", () => { open, loadOlder, create, + remove, send, streamSend, stopGeneration,