修复重新生成的 Bug

This commit is contained in:
GeekMaster
2025-09-01 14:28:20 +08:00
parent 14524f0559
commit 2e2b4ee370
2 changed files with 28 additions and 32 deletions

View File

@@ -104,18 +104,19 @@ func (h *ChatHandler) RegisterRoutes() {
// Chat 处理聊天请求 // Chat 处理聊天请求
func (h *ChatHandler) Chat(c *gin.Context) { func (h *ChatHandler) Chat(c *gin.Context) {
var input ChatInput
if err := c.ShouldBindJSON(&input); err != nil {
resp.ERROR(c, types.InvalidArgs)
return
}
// 设置SSE响应头 // 设置SSE响应头
c.Header("Prompt-Type", "text/event-stream") c.Header("Prompt-Type", "text/event-stream")
c.Header("Cache-Control", "no-cache") c.Header("Cache-Control", "no-cache")
c.Header("Connection", "keep-alive") c.Header("Connection", "keep-alive")
c.Header("X-Accel-Buffering", "no") 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()) ctx, cancel := context.WithCancel(c.Request.Context())
defer cancel() defer cancel()
@@ -259,6 +260,13 @@ func (h *ChatHandler) sendMessage(ctx context.Context, input ChatInput, c *gin.C
var historyMessages []model.ChatMessage var historyMessages []model.ChatMessage
dbSession := h.DB.Session(&gorm.Session{}).Where("chat_id", input.ChatId) dbSession := h.DB.Session(&gorm.Session{}).Where("chat_id", input.ChatId)
if input.LastMsgId > 0 { // 重新生成逻辑 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) dbSession = dbSession.Where("id < ?", input.LastMsgId)
// 删除对应的聊天记录 // 删除对应的聊天记录
h.DB.Debug().Where("chat_id", input.ChatId).Where("id >= ?", input.LastMsgId).Delete(&model.ChatMessage{}) h.DB.Debug().Where("chat_id", input.ChatId).Where("id >= ?", input.LastMsgId).Delete(&model.ChatMessage{})

View File

@@ -401,7 +401,6 @@ import { fetchEventSource } from '@microsoft/fetch-event-source'
import Clipboard from 'clipboard' import Clipboard from 'clipboard'
import { ElMessage, ElMessageBox } from 'element-plus' import { ElMessage, ElMessageBox } from 'element-plus'
import 'highlight.js/styles/a11y-dark.css' import 'highlight.js/styles/a11y-dark.css'
import { computed, nextTick, onMounted, ref, watch } from 'vue' import { computed, nextTick, onMounted, ref, watch } from 'vue'
import { useRouter } from 'vue-router' import { useRouter } from 'vue-router'
import { getUserToken } from '../store/session' import { getUserToken } from '../store/session'
@@ -704,35 +703,28 @@ const sendSSERequest = async (message) => {
}, },
body: JSON.stringify(message), body: JSON.stringify(message),
openWhenHidden: true, openWhenHidden: true,
// 禁用重试机制,避免连接断开后一直重试 // 重试机制,避免连接断开后一直重试
retry: false, retry: 3000,
// 设置重试延迟为0确保不重试 // 设置重试延迟为0确保不重试
retryDelay: 0, retryDelay: 3000,
// 设置最大重试次数为0 // 设置最大重试次数为0
maxRetries: 0, maxRetries: 3,
signal: abortController.value.signal, signal: abortController.value.signal,
onopen(response) { onopen(response) {
if (response.ok && response.status === 200) { if (response.ok && response.status === 200) {
console.log('SSE connection opened') console.log('SSE connection opened')
} else { } else {
const errorMsg = `连接失败 (状态码: ${response.status})`
ElMessage.error(errorMsg)
console.error('SSE connection failed', response) console.error('SSE connection failed', response)
isGenerating.value = false isGenerating.value = false
throw new Error(errorMsg)
} }
}, },
onmessage(msg) { onmessage(msg) {
try { try {
const data = JSON.parse(msg.data) const data = JSON.parse(msg.data)
if (data.type === 'error') { if (data.type === 'error') {
// ElMessage.error(data.body)
const reply = chatData.value[chatData.value.length - 1] const reply = chatData.value[chatData.value.length - 1]
if (reply) { if (reply) {
reply[ reply['content'].text = `<div class="text-red-500 p-3 rounded-md">${data.body}</div>`
'content'
].text = `<div class="bg-red-50 text-red-500 p-3 rounded-md">${data.body}</div>`
} }
isGenerating.value = false isGenerating.value = false
return return
@@ -825,9 +817,7 @@ const sendSSERequest = async (message) => {
// ElMessage.error('连接已断开,发生错误:' + err.message) // ElMessage.error('连接已断开,发生错误:' + err.message)
const reply = chatData.value[chatData.value.length - 1] const reply = chatData.value[chatData.value.length - 1]
if (reply) { if (reply) {
reply[ reply['content'].text = `<div class="text-red-500 p-3 rounded-md">${err.message}</div>`
'content'
].text = `<div class="bg-red-50 text-red-500 p-3 rounded-md">${err.message}</div>`
} }
}, },
onclose() { onclose() {
@@ -863,7 +853,7 @@ const sendMessage = (messageId = 0) => {
// 追加消息 // 追加消息
chatData.value.push({ chatData.value.push({
type: 'prompt', type: 'prompt',
id: randString(32), id: 0,
icon: loginUser.value.avatar, icon: loginUser.value.avatar,
content: { content: {
text: prompt.value, text: prompt.value,
@@ -1134,8 +1124,9 @@ const loadChatHistory = function (chatId) {
chat_id: chatId, chat_id: chatId,
role_id: roleId.value, role_id: roleId.value,
type: 'reply', type: 'reply',
id: randString(32), id: 0,
icon: _role['icon'], icon: _role['icon'],
isHello: true,
content: { content: {
text: _role['hello_msg'], text: _role['hello_msg'],
files: [], files: [],
@@ -1187,6 +1178,7 @@ const reGenerate = function (messageId) {
} }
console.log('messageId', messageId) console.log('messageId', messageId)
console.log('chatData.value', chatData.value)
// 判断 messageId 是整数 // 判断 messageId 是整数
if (messageId !== '' && isNaN(messageId)) { if (messageId !== '' && isNaN(messageId)) {
@@ -1194,14 +1186,10 @@ const reGenerate = function (messageId) {
return return
} }
chatData.value = chatData.value.filter((item) => item.id <= messageId) chatData.value = chatData.value.filter((item) => item.id < messageId && !item.isHello)
// 保存用户消息内容,填入输入框 const userPrompt = chatData.value.pop()
const userPrompt = chatData.value[chatData.value.length - 1].content.text prompt.value = userPrompt.content.text
// 删除用户消息 sendMessage(messageId)
const lastMessage = chatData.value.pop()
// 填入输入框
prompt.value = userPrompt
sendMessage(lastMessage.id)
// 将光标定位到输入框并聚焦 // 将光标定位到输入框并聚焦
nextTick(() => { nextTick(() => {
if (inputRef.value) { if (inputRef.value) {