fix: align /new restore and first-send routing flow

This commit is contained in:
JOJO 2026-04-05 01:22:30 +08:00
parent 7812d58a64
commit 3328d968d5
3 changed files with 91 additions and 5 deletions

View File

@ -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) {

View File

@ -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) {

View File

@ -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 {