From 2e2b4ee370e49702276bba7533a10eae488495a5 Mon Sep 17 00:00:00 2001 From: GeekMaster Date: Mon, 1 Sep 2025 14:28:20 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E9=87=8D=E6=96=B0=E7=94=9F?= =?UTF-8?q?=E6=88=90=E7=9A=84=20Bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/handler/chat_handler.go | 20 +++++++++++++------ web/src/views/ChatPlus.vue | 40 +++++++++++++------------------------ 2 files changed, 28 insertions(+), 32 deletions(-) diff --git a/api/handler/chat_handler.go b/api/handler/chat_handler.go index 899d7d07..d19b9528 100644 --- a/api/handler/chat_handler.go +++ b/api/handler/chat_handler.go @@ -104,18 +104,19 @@ func (h *ChatHandler) RegisterRoutes() { // Chat 处理聊天请求 func (h *ChatHandler) Chat(c *gin.Context) { - var input ChatInput - if err := c.ShouldBindJSON(&input); err != nil { - resp.ERROR(c, types.InvalidArgs) - return - } - // 设置SSE响应头 c.Header("Prompt-Type", "text/event-stream") c.Header("Cache-Control", "no-cache") c.Header("Connection", "keep-alive") c.Header("X-Accel-Buffering", "no") + var input ChatInput + if err := c.ShouldBindJSON(&input); err != nil { + pushMessage(c, ChatEventError, types.InvalidArgs) + c.Abort() + return + } + ctx, cancel := context.WithCancel(c.Request.Context()) defer cancel() @@ -259,6 +260,13 @@ func (h *ChatHandler) sendMessage(ctx context.Context, input ChatInput, c *gin.C var historyMessages []model.ChatMessage dbSession := h.DB.Session(&gorm.Session{}).Where("chat_id", input.ChatId) if input.LastMsgId > 0 { // 重新生成逻辑 + var lastMessage model.ChatMessage + err = dbSession.Where("id <= ?", input.LastMsgId).Where("type", types.PromptMsg).First(&lastMessage).Error + if err != nil { + input.LastMsgId = 0 + } else { + input.LastMsgId = lastMessage.Id + } dbSession = dbSession.Where("id < ?", input.LastMsgId) // 删除对应的聊天记录 h.DB.Debug().Where("chat_id", input.ChatId).Where("id >= ?", input.LastMsgId).Delete(&model.ChatMessage{}) diff --git a/web/src/views/ChatPlus.vue b/web/src/views/ChatPlus.vue index 65e751e0..a3cfc410 100644 --- a/web/src/views/ChatPlus.vue +++ b/web/src/views/ChatPlus.vue @@ -401,7 +401,6 @@ import { fetchEventSource } from '@microsoft/fetch-event-source' import Clipboard from 'clipboard' import { ElMessage, ElMessageBox } from 'element-plus' import 'highlight.js/styles/a11y-dark.css' - import { computed, nextTick, onMounted, ref, watch } from 'vue' import { useRouter } from 'vue-router' import { getUserToken } from '../store/session' @@ -704,35 +703,28 @@ const sendSSERequest = async (message) => { }, body: JSON.stringify(message), openWhenHidden: true, - // 禁用重试机制,避免连接断开后一直重试 - retry: false, + // 重试机制,避免连接断开后一直重试 + retry: 3000, // 设置重试延迟为0,确保不重试 - retryDelay: 0, + retryDelay: 3000, // 设置最大重试次数为0 - maxRetries: 0, + maxRetries: 3, signal: abortController.value.signal, onopen(response) { if (response.ok && response.status === 200) { console.log('SSE connection opened') } else { - const errorMsg = `连接失败 (状态码: ${response.status})` - ElMessage.error(errorMsg) console.error('SSE connection failed', response) isGenerating.value = false - - throw new Error(errorMsg) } }, onmessage(msg) { try { const data = JSON.parse(msg.data) if (data.type === 'error') { - // ElMessage.error(data.body) const reply = chatData.value[chatData.value.length - 1] if (reply) { - reply[ - 'content' - ].text = `
${data.body}
` + reply['content'].text = `
${data.body}
` } isGenerating.value = false return @@ -825,9 +817,7 @@ const sendSSERequest = async (message) => { // ElMessage.error('连接已断开,发生错误:' + err.message) const reply = chatData.value[chatData.value.length - 1] if (reply) { - reply[ - 'content' - ].text = `
${err.message}
` + reply['content'].text = `
${err.message}
` } }, onclose() { @@ -863,7 +853,7 @@ const sendMessage = (messageId = 0) => { // 追加消息 chatData.value.push({ type: 'prompt', - id: randString(32), + id: 0, icon: loginUser.value.avatar, content: { text: prompt.value, @@ -1134,8 +1124,9 @@ const loadChatHistory = function (chatId) { chat_id: chatId, role_id: roleId.value, type: 'reply', - id: randString(32), + id: 0, icon: _role['icon'], + isHello: true, content: { text: _role['hello_msg'], files: [], @@ -1187,6 +1178,7 @@ const reGenerate = function (messageId) { } console.log('messageId', messageId) + console.log('chatData.value', chatData.value) // 判断 messageId 是整数 if (messageId !== '' && isNaN(messageId)) { @@ -1194,14 +1186,10 @@ const reGenerate = function (messageId) { return } - chatData.value = chatData.value.filter((item) => item.id <= messageId) - // 保存用户消息内容,填入输入框 - const userPrompt = chatData.value[chatData.value.length - 1].content.text - // 删除用户消息 - const lastMessage = chatData.value.pop() - // 填入输入框 - prompt.value = userPrompt - sendMessage(lastMessage.id) + chatData.value = chatData.value.filter((item) => item.id < messageId && !item.isHello) + const userPrompt = chatData.value.pop() + prompt.value = userPrompt.content.text + sendMessage(messageId) // 将光标定位到输入框并聚焦 nextTick(() => { if (inputRef.value) {