From 4d154ebdd533232b55cebfb285939a63511b98cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=97=A0=E9=97=BB=E9=A3=8E?= Date: Tue, 16 Jun 2026 16:02:44 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E8=81=8A=E5=A4=A9=E7=BB=86?= =?UTF-8?q?=E8=8A=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/ops_vue_js/src/i18n/en.json | 2 + frontend/ops_vue_js/src/i18n/zh-CN.json | 2 + .../src/views/aichat/AiChatView.vue | 53 +++++++++++++++++-- 3 files changed, 54 insertions(+), 3 deletions(-) diff --git a/frontend/ops_vue_js/src/i18n/en.json b/frontend/ops_vue_js/src/i18n/en.json index 4d78111..d1f1d6f 100644 --- a/frontend/ops_vue_js/src/i18n/en.json +++ b/frontend/ops_vue_js/src/i18n/en.json @@ -87,6 +87,8 @@ "no_server_chats": "No server chats", "no_browser_chats": "No browser chats", "delete_chat": "Delete chat", + "delete_chat_confirm": "Are you sure you want to delete this chat? This action cannot be undone.", + "login_required": "Please log in before chatting with AI", "rename_chat": "Rename chat", "load_conversations_failed": "Failed to load chat list", "load_chat_failed": "Failed to load chat", diff --git a/frontend/ops_vue_js/src/i18n/zh-CN.json b/frontend/ops_vue_js/src/i18n/zh-CN.json index a6f02f6..b30d9d7 100644 --- a/frontend/ops_vue_js/src/i18n/zh-CN.json +++ b/frontend/ops_vue_js/src/i18n/zh-CN.json @@ -87,6 +87,8 @@ "no_server_chats": "暂无服务端聊天", "no_browser_chats": "暂无浏览器聊天", "delete_chat": "删除聊天", + "delete_chat_confirm": "确定要删除该聊天吗?此操作不可恢复。", + "login_required": "请先登录后再使用 AI 聊天", "rename_chat": "重命名聊天", "load_conversations_failed": "加载聊天列表失败", "load_chat_failed": "加载聊天失败", diff --git a/frontend/ops_vue_js/src/views/aichat/AiChatView.vue b/frontend/ops_vue_js/src/views/aichat/AiChatView.vue index 62a2aa8..38b918d 100644 --- a/frontend/ops_vue_js/src/views/aichat/AiChatView.vue +++ b/frontend/ops_vue_js/src/views/aichat/AiChatView.vue @@ -12,6 +12,7 @@ import { import { usePageTitle } from '@/composables/usePageTitle' import { useToastStore } from '@/stores/toast' import { useUserStore } from '@/stores/user' +import ConfirmDialog from '@/components/ConfirmDialog.vue' const props = defineProps({ embedded: { @@ -50,6 +51,9 @@ const activeLocalId = ref('') const activeServerId = ref(0) const loadingConversations = ref(false) +const confirmDeleteVisible = ref(false) +const pendingDeleteTarget = ref(null) // { type: 'local' | 'server', id } + const MAX_IMAGE_SIZE = 4 * 1024 * 1024 const ALLOWED_IMAGE_TYPES = ['image/jpeg', 'image/png', 'image/webp', 'image/gif'] const LOCAL_STORAGE_KEY = 'ops:aichat:local:v1' @@ -319,6 +323,32 @@ function clearChat() { async function deleteLocalConversation(localId) { if (pending.value) return + pendingDeleteTarget.value = { type: 'local', id: localId } + confirmDeleteVisible.value = true +} + +async function deleteServerConversation(id) { + if (pending.value) return + pendingDeleteTarget.value = { type: 'server', id } + confirmDeleteVisible.value = true +} + +async function handleConfirmDelete() { + const target = pendingDeleteTarget.value + pendingDeleteTarget.value = null + if (!target) return + if (target.type === 'local') { + doDeleteLocalConversation(target.id) + } else if (target.type === 'server') { + await doDeleteServerConversation(target.id) + } +} + +function handleCancelDelete() { + pendingDeleteTarget.value = null +} + +function doDeleteLocalConversation(localId) { localConversations.value = localConversations.value.filter((item) => item.localId !== localId) saveLocalConversations() if (activeLocalId.value === localId) { @@ -330,9 +360,7 @@ async function deleteLocalConversation(localId) { } } -async function deleteServerConversation(id) { - if (pending.value) return - if (!window.confirm(t('aichat.delete_chat'))) return +async function doDeleteServerConversation(id) { try { const res = await deleteAIChatConversation(id) if (res.errCode === 0) { @@ -611,14 +639,24 @@ function renderMarkdown(value) { function sendQuickPrompt(prompt) { if (pending.value) return + if (!ensureLoggedIn()) return inputText.value = prompt sendMessage() } +function ensureLoggedIn() { + if (!userStore.isLoggedIn) { + toast.warning(t('aichat.login_required')) + return false + } + return true +} + async function sendMessage() { const text = inputText.value.trim() const image = selectedImage.value if ((!text && !image) || pending.value) return + if (!ensureLoggedIn()) return const clientLocalId = activeLocalId.value || createLocalId() activeLocalId.value = clientLocalId @@ -1039,6 +1077,15 @@ async function sendMessage() { + +