feat: add task confirmation when switching conversations

- Prompt user to confirm when switching/creating conversation with active task
- Automatically stop running task after user confirmation
- Filter out events from previous conversation to prevent cross-talk
- Show toast notification after task is stopped

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
JOJO 2026-03-08 03:32:35 +08:00
parent 801d20591c
commit 0e4f625338
2 changed files with 107 additions and 0 deletions

View File

@ -169,6 +169,46 @@ export const conversationMethods = {
return;
}
// 检查是否有运行中的任务,如果有则提示用户
let hasActiveTask = false;
try {
const { useTaskStore } = await import('../../stores/task');
const taskStore = useTaskStore();
if (taskStore.hasActiveTask) {
hasActiveTask = true;
// 显示提示
const confirmed = await this.confirmAction({
title: '切换对话',
message: '当前有任务正在执行,切换对话后任务会停止。确定要切换吗?',
confirmText: '切换',
cancelText: '取消'
});
if (!confirmed) {
// 用户取消切换
this.suppressTitleTyping = false;
this.titleReady = true;
return;
}
// 用户确认,停止任务
debugLog('[切换对话] 用户确认,正在停止任务...');
await taskStore.cancelTask();
taskStore.clearTask();
// 重置任务相关状态
this.streamingMessage = false;
this.taskInProgress = false;
this.stopRequested = false;
debugLog('[切换对话] 任务已停止');
}
} catch (error) {
console.error('[切换对话] 检查/停止任务失败:', error);
}
try {
// 1. 调用加载API
const response = await fetch(`/api/conversations/${conversationId}/load`, {
@ -205,6 +245,16 @@ export const conversationMethods = {
messagesLen: Array.isArray(this.messages) ? this.messages.length : 'n/a'
});
// 如果停止了任务,显示提示
if (hasActiveTask) {
this.uiPushToast({
title: '任务已停止',
message: '切换对话后,之前的任务已停止',
type: 'info',
duration: 3000
});
}
} else {
console.error('对话加载失败:', result.message);
this.suppressTitleTyping = false;
@ -247,6 +297,44 @@ export const conversationMethods = {
});
this.logMessageState('createNewConversation:start');
// 检查是否有运行中的任务,如果有则提示用户
let hasActiveTask = false;
try {
const { useTaskStore } = await import('../../stores/task');
const taskStore = useTaskStore();
if (taskStore.hasActiveTask) {
hasActiveTask = true;
// 显示提示
const confirmed = await this.confirmAction({
title: '创建新对话',
message: '当前有任务正在执行,创建新对话后任务会停止。确定要创建吗?',
confirmText: '创建',
cancelText: '取消'
});
if (!confirmed) {
// 用户取消创建
return;
}
// 用户确认,停止任务
debugLog('[创建新对话] 用户确认,正在停止任务...');
await taskStore.cancelTask();
taskStore.clearTask();
// 重置任务相关状态
this.streamingMessage = false;
this.taskInProgress = false;
this.stopRequested = false;
debugLog('[创建新对话] 任务已停止');
}
} catch (error) {
console.error('[创建新对话] 检查/停止任务失败:', error);
}
try {
const response = await fetch('/api/conversations', {
method: 'POST',
@ -294,6 +382,16 @@ export const conversationMethods = {
newConversationId,
conversationsLen: Array.isArray(this.conversations) ? this.conversations.length : 'n/a'
});
// 如果停止了任务,显示提示
if (hasActiveTask) {
this.uiPushToast({
title: '任务已停止',
message: '创建新对话后,之前的任务已停止',
type: 'info',
duration: 3000
});
}
} else {
console.error('创建对话失败:', result.message);
this.uiPushToast({

View File

@ -18,6 +18,15 @@ export const taskPollingMethods = {
const eventData = event.data || {};
const eventIdx = event.idx;
// 检查事件的 conversation_id 是否匹配当前对话
// 如果不匹配,忽略该事件(避免切换对话后旧任务的事件显示到新对话中)
if (eventData.conversation_id && this.currentConversationId) {
if (eventData.conversation_id !== this.currentConversationId) {
debugLog(`[TaskPolling] 忽略不匹配的事件 #${eventIdx}: ${eventType}, 事件对话=${eventData.conversation_id}, 当前对话=${this.currentConversationId}`);
return;
}
}
debugLog(`[TaskPolling] 处理事件 #${eventIdx}: ${eventType}`, eventData);
// 根据事件类型调用对应的处理方法