更新聊天细节
This commit is contained in:
@@ -87,6 +87,8 @@
|
|||||||
"no_server_chats": "No server chats",
|
"no_server_chats": "No server chats",
|
||||||
"no_browser_chats": "No browser chats",
|
"no_browser_chats": "No browser chats",
|
||||||
"delete_chat": "Delete chat",
|
"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",
|
"rename_chat": "Rename chat",
|
||||||
"load_conversations_failed": "Failed to load chat list",
|
"load_conversations_failed": "Failed to load chat list",
|
||||||
"load_chat_failed": "Failed to load chat",
|
"load_chat_failed": "Failed to load chat",
|
||||||
|
|||||||
@@ -87,6 +87,8 @@
|
|||||||
"no_server_chats": "暂无服务端聊天",
|
"no_server_chats": "暂无服务端聊天",
|
||||||
"no_browser_chats": "暂无浏览器聊天",
|
"no_browser_chats": "暂无浏览器聊天",
|
||||||
"delete_chat": "删除聊天",
|
"delete_chat": "删除聊天",
|
||||||
|
"delete_chat_confirm": "确定要删除该聊天吗?此操作不可恢复。",
|
||||||
|
"login_required": "请先登录后再使用 AI 聊天",
|
||||||
"rename_chat": "重命名聊天",
|
"rename_chat": "重命名聊天",
|
||||||
"load_conversations_failed": "加载聊天列表失败",
|
"load_conversations_failed": "加载聊天列表失败",
|
||||||
"load_chat_failed": "加载聊天失败",
|
"load_chat_failed": "加载聊天失败",
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import {
|
|||||||
import { usePageTitle } from '@/composables/usePageTitle'
|
import { usePageTitle } from '@/composables/usePageTitle'
|
||||||
import { useToastStore } from '@/stores/toast'
|
import { useToastStore } from '@/stores/toast'
|
||||||
import { useUserStore } from '@/stores/user'
|
import { useUserStore } from '@/stores/user'
|
||||||
|
import ConfirmDialog from '@/components/ConfirmDialog.vue'
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
embedded: {
|
embedded: {
|
||||||
@@ -50,6 +51,9 @@ const activeLocalId = ref('')
|
|||||||
const activeServerId = ref(0)
|
const activeServerId = ref(0)
|
||||||
const loadingConversations = ref(false)
|
const loadingConversations = ref(false)
|
||||||
|
|
||||||
|
const confirmDeleteVisible = ref(false)
|
||||||
|
const pendingDeleteTarget = ref(null) // { type: 'local' | 'server', id }
|
||||||
|
|
||||||
const MAX_IMAGE_SIZE = 4 * 1024 * 1024
|
const MAX_IMAGE_SIZE = 4 * 1024 * 1024
|
||||||
const ALLOWED_IMAGE_TYPES = ['image/jpeg', 'image/png', 'image/webp', 'image/gif']
|
const ALLOWED_IMAGE_TYPES = ['image/jpeg', 'image/png', 'image/webp', 'image/gif']
|
||||||
const LOCAL_STORAGE_KEY = 'ops:aichat:local:v1'
|
const LOCAL_STORAGE_KEY = 'ops:aichat:local:v1'
|
||||||
@@ -319,6 +323,32 @@ function clearChat() {
|
|||||||
|
|
||||||
async function deleteLocalConversation(localId) {
|
async function deleteLocalConversation(localId) {
|
||||||
if (pending.value) return
|
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)
|
localConversations.value = localConversations.value.filter((item) => item.localId !== localId)
|
||||||
saveLocalConversations()
|
saveLocalConversations()
|
||||||
if (activeLocalId.value === localId) {
|
if (activeLocalId.value === localId) {
|
||||||
@@ -330,9 +360,7 @@ async function deleteLocalConversation(localId) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function deleteServerConversation(id) {
|
async function doDeleteServerConversation(id) {
|
||||||
if (pending.value) return
|
|
||||||
if (!window.confirm(t('aichat.delete_chat'))) return
|
|
||||||
try {
|
try {
|
||||||
const res = await deleteAIChatConversation(id)
|
const res = await deleteAIChatConversation(id)
|
||||||
if (res.errCode === 0) {
|
if (res.errCode === 0) {
|
||||||
@@ -611,14 +639,24 @@ function renderMarkdown(value) {
|
|||||||
|
|
||||||
function sendQuickPrompt(prompt) {
|
function sendQuickPrompt(prompt) {
|
||||||
if (pending.value) return
|
if (pending.value) return
|
||||||
|
if (!ensureLoggedIn()) return
|
||||||
inputText.value = prompt
|
inputText.value = prompt
|
||||||
sendMessage()
|
sendMessage()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function ensureLoggedIn() {
|
||||||
|
if (!userStore.isLoggedIn) {
|
||||||
|
toast.warning(t('aichat.login_required'))
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
async function sendMessage() {
|
async function sendMessage() {
|
||||||
const text = inputText.value.trim()
|
const text = inputText.value.trim()
|
||||||
const image = selectedImage.value
|
const image = selectedImage.value
|
||||||
if ((!text && !image) || pending.value) return
|
if ((!text && !image) || pending.value) return
|
||||||
|
if (!ensureLoggedIn()) return
|
||||||
|
|
||||||
const clientLocalId = activeLocalId.value || createLocalId()
|
const clientLocalId = activeLocalId.value || createLocalId()
|
||||||
activeLocalId.value = clientLocalId
|
activeLocalId.value = clientLocalId
|
||||||
@@ -1039,6 +1077,15 @@ async function sendMessage() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<ConfirmDialog
|
||||||
|
v-model="confirmDeleteVisible"
|
||||||
|
:title="t('aichat.delete_chat')"
|
||||||
|
:message="t('aichat.delete_chat_confirm')"
|
||||||
|
:danger="true"
|
||||||
|
@confirm="handleConfirmDelete"
|
||||||
|
@cancel="handleCancelDelete"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user