fix: align /new restore and first-send routing flow
This commit is contained in:
parent
7812d58a64
commit
3328d968d5
@ -158,7 +158,12 @@ export const conversationMethods = {
|
||||
this.hasMoreConversations = data.data.has_more;
|
||||
debugLog(`已加载 ${this.conversations.length} 个对话`);
|
||||
|
||||
if (this.conversationsOffset === 0 && !this.currentConversationId && this.conversations.length > 0) {
|
||||
if (
|
||||
this.conversationsOffset === 0 &&
|
||||
!this.currentConversationId &&
|
||||
this.conversations.length > 0 &&
|
||||
!this.isExplicitNewConversationRoute()
|
||||
) {
|
||||
// 只有在初始化完成后,才自动加载第一个对话
|
||||
// 避免与 bootstrapRoute 冲突
|
||||
if (this.initialRouteResolved) {
|
||||
|
||||
@ -198,6 +198,49 @@ export const messageMethods = {
|
||||
}, 320);
|
||||
}
|
||||
|
||||
let targetConversationId = this.currentConversationId;
|
||||
if (!targetConversationId) {
|
||||
try {
|
||||
const createResp = await fetch('/api/conversations', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
thinking_mode: this.thinkingMode,
|
||||
mode: this.runMode
|
||||
})
|
||||
});
|
||||
const createResult = await createResp.json().catch(() => ({}));
|
||||
if (!createResp.ok || !createResult?.success || !createResult?.conversation_id) {
|
||||
throw new Error(createResult?.message || createResult?.error || '创建对话失败');
|
||||
}
|
||||
targetConversationId = createResult.conversation_id;
|
||||
this.skipConversationHistoryReload = true;
|
||||
this.currentConversationId = targetConversationId;
|
||||
this.currentConversationTitle = '新对话';
|
||||
this.conversations = [
|
||||
{
|
||||
id: targetConversationId,
|
||||
title: '新对话',
|
||||
updated_at: new Date().toISOString(),
|
||||
total_messages: 0,
|
||||
total_tools: 0
|
||||
},
|
||||
...this.conversations.filter((conv) => conv && conv.id !== targetConversationId)
|
||||
];
|
||||
const pathFragment = this.stripConversationPrefix(targetConversationId);
|
||||
history.replaceState({ conversationId: targetConversationId }, '', `/${pathFragment}`);
|
||||
} catch (error) {
|
||||
this.uiPushToast({
|
||||
title: '发送失败',
|
||||
message: error?.message || '创建新对话失败,请重试',
|
||||
type: 'error'
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// 标记任务进行中,直到任务完成或用户手动停止
|
||||
this.taskInProgress = true;
|
||||
this.chatAddUserMessage(message, images, videos);
|
||||
@ -210,7 +253,7 @@ export const messageMethods = {
|
||||
this.clearProcessedEvents();
|
||||
}
|
||||
|
||||
await taskStore.createTask(message, images, videos, this.currentConversationId);
|
||||
await taskStore.createTask(message, images, videos, targetConversationId);
|
||||
|
||||
debugLog('[Message] 任务已创建,开始轮询');
|
||||
} catch (error) {
|
||||
|
||||
@ -964,6 +964,27 @@ export const uiMethods = {
|
||||
return renderMarkdownHelper(content, isStreaming);
|
||||
},
|
||||
|
||||
isExplicitNewConversationRoute() {
|
||||
const normalizedPath = window.location.pathname.replace(/^\/+|\/+$/g, '');
|
||||
return normalizedPath === 'new';
|
||||
},
|
||||
|
||||
async getRunningTaskConversationId() {
|
||||
try {
|
||||
const resp = await fetch('/api/tasks');
|
||||
if (!resp.ok) {
|
||||
return null;
|
||||
}
|
||||
const payload = await resp.json();
|
||||
const tasks = Array.isArray(payload?.data) ? payload.data : [];
|
||||
const runningTask = tasks.find((task: any) => task?.status === 'running' && task?.conversation_id);
|
||||
return runningTask?.conversation_id || null;
|
||||
} catch (error) {
|
||||
console.warn('获取运行中任务失败:', error);
|
||||
return null;
|
||||
}
|
||||
},
|
||||
|
||||
async bootstrapRoute() {
|
||||
// 在路由解析期间抑制标题动画,避免预置"新对话"闪烁
|
||||
this.suppressTitleTyping = true;
|
||||
@ -971,13 +992,16 @@ export const uiMethods = {
|
||||
this.currentConversationTitle = '';
|
||||
this.titleTypingText = '';
|
||||
const path = window.location.pathname.replace(/^\/+/, '');
|
||||
if (!path || path === 'new') {
|
||||
if (!path || this.isExplicitNewConversationRoute()) {
|
||||
this.currentConversationId = null;
|
||||
this.currentConversationTitle = '新对话';
|
||||
this.logMessageState('bootstrapRoute:clear-messages-for-new');
|
||||
this.messages = [];
|
||||
this.titleReady = true;
|
||||
this.suppressTitleTyping = false;
|
||||
this.startTitleTyping('新对话', { animate: false });
|
||||
this.initialRouteResolved = true;
|
||||
this.refreshBlankHeroState();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1157,8 +1181,17 @@ export const uiMethods = {
|
||||
}
|
||||
|
||||
// 获取当前对话信息
|
||||
const isExplicitNewRoute = this.isExplicitNewConversationRoute();
|
||||
const runningConversationId = await this.getRunningTaskConversationId();
|
||||
const statusConversationId = statusData.conversation && statusData.conversation.current_id;
|
||||
if (statusConversationId && !this.currentConversationId) {
|
||||
const resumeConversationId = statusConversationId || runningConversationId;
|
||||
const shouldResumeOnNewRoute = isExplicitNewRoute && !!runningConversationId;
|
||||
|
||||
if (
|
||||
resumeConversationId &&
|
||||
!this.currentConversationId &&
|
||||
(!isExplicitNewRoute || shouldResumeOnNewRoute)
|
||||
) {
|
||||
this.skipConversationHistoryReload = true;
|
||||
// 首次从状态恢复对话时,避免 socket 的 conversation_loaded 再次触发历史加载
|
||||
this.skipConversationLoadedEvent = true;
|
||||
@ -1166,7 +1199,12 @@ export const uiMethods = {
|
||||
this.titleReady = false;
|
||||
this.currentConversationTitle = '';
|
||||
this.titleTypingText = '';
|
||||
this.currentConversationId = statusConversationId;
|
||||
this.currentConversationId = resumeConversationId;
|
||||
const pathFragment = this.stripConversationPrefix(resumeConversationId);
|
||||
const currentPath = window.location.pathname.replace(/^\/+/, '');
|
||||
if (currentPath !== pathFragment) {
|
||||
history.replaceState({ conversationId: resumeConversationId }, '', `/${pathFragment}`);
|
||||
}
|
||||
|
||||
// 如果有当前对话,尝试获取标题和历史
|
||||
try {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user