首页:删除气泡重新生成功能

- 移除失败气泡与 AI/用户消息操作栏的重新生成入口
- 清理 retry/regenerate 事件链、handleRetry 及 retryQuestion 字段
- 保留失败/空回复提示文本、复制与删除操作

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2026-08-21 18:24:03 +08:00
co-authored by Claude
parent 918ae96f71
commit c51d0dc2ca
3 changed files with 2 additions and 101 deletions
+1 -41
View File
@@ -53,10 +53,6 @@
v-html="renderAnswer(msg.content)"
@click="handleAnswerClick"
></div>
<!-- 失败重试工作流结果不提供文本重试需重新提交表单卡片 -->
<button v-if="isErrorMsg(msg) && msg.recordType !== 'workflow'" type="button" class="retry-btn" @click="emit('retry', msg)">
<span class="retry-icon"></span> 重新生成
</button>
</template>
</div>
<!-- 工作流执行产出文件卡片挂在结果消息上预览/下载/删除 -->
@@ -70,9 +66,6 @@
/>
<!-- AI 消息操作栏hover 显示 -->
<div v-if="!msg.isUser && msg.content && !isErrorMsg(msg)" class="msg-actions">
<button v-if="msg.recordType !== 'workflow'" class="msg-action" title="重新生成" @click="emit('regenerate', msg)">
<el-icon><RefreshRight /></el-icon>
</button>
<button class="msg-action" title="复制回答" @click="copyText(msg.content)">
<el-icon><DocumentCopy /></el-icon>
</button>
@@ -82,9 +75,6 @@
</div>
<!-- 用户消息操作栏hover 显示重新生成 + 删除 -->
<div v-if="msg.isUser" class="msg-actions">
<button class="msg-action" title="重新生成" @click="emit('regenerate', msg)">
<el-icon><RefreshRight /></el-icon>
</button>
<button v-if="msg.recordId" class="msg-action is-danger" title="删除对话" @click="emit('delete', msg)">
<el-icon><Delete /></el-icon>
</button>
@@ -99,7 +89,7 @@
<script setup lang="ts">
import { computed, nextTick, onMounted, reactive, ref, watch } from 'vue';
import { ElMessage } from 'element-plus';
import { Delete, DocumentCopy, RefreshRight } from '@element-plus/icons-vue';
import { Delete, DocumentCopy } from '@element-plus/icons-vue';
import 'highlight.js/styles/github-dark.css';
import { renderMarkdown } from '../utils/markdown';
import type { WorkflowOutput } from '../utils/flowDsl';
@@ -115,7 +105,6 @@ interface ChatMessage {
loading?: boolean;
thinking?: string;
thinkingSeconds?: number;
retryQuestion?: string;
// 后端记录 id / 类型(来自 session/get 的每条结果),存在时才显示删除按钮
recordId?: string;
recordType?: string;
@@ -131,8 +120,6 @@ interface ChatMessage {
}
interface Emits {
(e: 'retry', msg: ChatMessage): void;
(e: 'regenerate', msg: ChatMessage): void;
(e: 'delete', msg: ChatMessage): void;
(e: 'form-submit', msg: ChatMessage, payload: any): void;
(e: 'form-retry', msg: ChatMessage, payload: any): void;
@@ -481,33 +468,6 @@ onMounted(() => {
}
}
/* 失败重试 */
.retry-btn {
display: inline-flex;
align-items: center;
gap: 5px;
margin-top: 8px;
padding: 7px 14px;
border: 1px solid #fecaca;
border-radius: 10px;
background: #fef2f2;
color: #dc2626;
font-size: 12px;
font-weight: 500;
cursor: pointer;
transition: all 0.15s;
&:hover {
background: #fee2e2;
border-color: #fca5a5;
}
.retry-icon {
font-size: 14px;
line-height: 1;
}
}
/* 思考区:DeepSeek 风格折叠块 */
.thinking-block {
margin: 0 0 12px;
@@ -10,8 +10,6 @@
:loading-more="loadingMore"
:execute-request="executeRequest"
class="chat-list-scroll"
@retry="emit('retry', $event)"
@regenerate="emit('regenerate', $event)"
@delete="emit('delete', $event)"
@form-submit="(msg: any, payload: any) => emit('form-submit', msg, payload)"
@form-retry="(msg: any, payload: any) => emit('form-retry', msg, payload)"
@@ -70,8 +68,6 @@ interface Props {
}
interface Emits {
(e: 'retry', msg: any): void;
(e: 'regenerate', msg: any): void;
(e: 'workflow-select', id: string, isTemplate?: boolean): void;
(e: 'delete', msg: any): void;
(e: 'form-submit', msg: any, payload: any): void;
+1 -56
View File
@@ -29,8 +29,6 @@
:has-more="currentSessionHasMore"
:loading-more="currentSessionLoadingMore"
:execute-request="executeRequest"
@retry="handleRetry"
@regenerate="handleRetry"
@delete="handleDeleteMessage"
@form-submit="handleFormSubmit"
@form-retry="handleFormRetry"
@@ -129,7 +127,6 @@ interface ChatMessage {
loading?: boolean;
thinking?: string;
thinkingSeconds?: number;
retryQuestion?: string;
// 后端记录 id / 类型(来自 session/get 的每条结果),用于删除对话记录
recordId?: string;
recordType?: string;
@@ -855,56 +852,6 @@ const handleSend = async (message: string) => {
await runChat(sid, sessionId, message);
};
// ===== 失败重试:重新发送同一条用户消息 =====
const handleRetry = async (msg: ChatMessage) => {
// 工作流结果消息不提供文本重试(重试需重新填写表单卡片提交)
if (msg.recordType === 'workflow') return;
let sid = '';
for (const [k, list] of sessionMessages.value) {
if (list.some((m) => m.id === msg.id)) {
sid = k;
break;
}
}
if (!sid || sendingSessions[sid]) return;
const session = historyList.value.find((h) => h.id === sid);
if (!session) return;
const list = sessionMessages.value.get(sid) || [];
const idx = list.findIndex((m) => m.id === msg.id);
if (idx < 0) return;
// 待重发的用户问题:用户消息直接用自身内容;失败消息优先记录的原文,其次向上找最近一条用户消息
let question = msg.isUser ? msg.content : (msg.retryQuestion || '');
if (!question) {
for (let i = idx - 1; i >= 0; i--) {
if (list[i].isUser) {
question = list[i].content;
break;
}
}
}
if (!question) return;
// 移除待重生成的消息:用户消息连同紧随其后的 AI 回复一并移除(避免旧回复残留错位);AI 回复只移除自身
if (msg.isUser && idx + 1 < list.length && !list[idx + 1].isUser && list[idx + 1].type !== 'form') {
list.splice(idx, 2);
} else {
list.splice(idx, 1);
}
// 用户消息重新生成:runChat 只追加 AI 气泡、不会补用户消息,这里先把用户问题重新追加进消息流,避免用户气泡消失
if (msg.isUser) {
list.push({ id: 'msg-' + Date.now() + '-user', content: question, time: formatTime(new Date()), isUser: true });
}
sendingSessions[sid] = true;
session.status = 'executing';
const sessionId = resolveSessionIdForConnect(session);
try {
await runChat(sid, sessionId, question);
} catch {
session.status = 'failed';
} finally {
delete sendingSessions[sid];
}
};
// ===== 删除会话内对话记录:删除选中的 AI 回复 + 紧邻其上方的用户问题(同一 record 时去重)=====
const handleDeleteMessage = async (msg: ChatMessage) => {
const sid = activeHistoryId.value;
@@ -1382,16 +1329,14 @@ const runChat = async (sid: string, sessionId: string, message: string) => {
list[aiIdx].loading = false;
list[aiIdx].content = content;
list[aiIdx].thinking = '';
list[aiIdx].retryQuestion = message;
} else {
pushToSession(sid, { id: 'msg-' + Date.now() + '-fail', content, time: formatTime(new Date()), isUser: false });
}
} else if (list && aiIdx >= 0) {
// 成功兜底:后端未推任何回复内容时,给出明确提示并允许重新生成(避免空白气泡)
// 成功兜底:后端未推任何回复内容时,给出明确提示(避免空白气泡)
const ai = list[aiIdx];
if (!ai.content) {
ai.content = '⚠️ 未收到回复内容,请重试';
ai.retryQuestion = message;
}
}
// 更新会话状态