优化: AI Chat全栈多批审查修复与架构清理(risk_level清理/路由解耦/工具渲染/测试补测/死代码)

This commit is contained in:
2026-06-18 22:57:19 +08:00
parent 0ca5d9805f
commit a2871a66e0
87 changed files with 5720 additions and 3012 deletions

View File

@@ -22,6 +22,26 @@ const t = ((i18n as any).global.t as (k: string, named?: Record<string, unknown>
async function loadConversations() {
try {
state.conversations = await aiApi.listConversations()
// 虚拟项保底:活跃会话未落库(懒创建——首条消息前 DB 无记录)时,侧栏显示虚拟占位项。
// 后端 ai_conversation_create 仅生成 id 存内存不落库,首条消息发送后 save_conversation 才写库。
// 此处 active 会话不在 DB 列表时补一个虚拟项,实现「点新建立即出现在侧栏,不发消息不落库」。
// 首条消息落库后 AiCompleted/AiError 触发的 loadConversations 拉到同 id 真实记录,虚拟项被替代无重复。
if (state.activeConversationId
&& !state.conversations.some(c => c.id === state.activeConversationId)) {
const now = String(Date.now())
state.conversations.unshift({
id: state.activeConversationId,
title: null,
provider_id: null,
model: null,
archived: false,
pinned: false,
prompt_tokens: 0,
completion_tokens: 0,
created_at: now,
updated_at: now,
})
}
// 恢复上次活跃对话(仅在首次加载、ID 仍有效且当前无活跃对话时)
const pending = appSettings.get<string | null>('df-ai-active-conv', null)
if (pending && !state.activeConversationId && state.conversations.some(c => c.id === pending)) {
@@ -100,7 +120,8 @@ export async function switchConversation(id: string) {
role: m.role,
content: m.content || '',
model: m.model,
timestamp: Date.now(),
// 用后端持久化的真实时间(BUG-260618-01);老数据无 timestamp 字段回退 Date.now()
timestamp: typeof m.timestamp === 'number' ? m.timestamp : Date.now(),
// F-260614-05 Phase 2b: 透传 parts(多模态 Image 片)。后端序列化的 ContentPart[]
// 含 type:'text'|'image' discriminator + url/base64/media_type/alt 字段,
// 此处原样透传供 AiChat.vue 用户气泡渲染 <img>(base64 模式持久化层已替换占位 Text 片,
@@ -230,6 +251,12 @@ function toggleArchivedFold() {
persistUiState()
}
/** 折叠/展开时间分组(today/yesterday/earlier) */
function toggleGroupFold(key: string) {
state.foldedGroups[key] = !state.foldedGroups[key]
persistUiState()
}
/** 展开/收起侧栏(会话列表) */
function toggleSidebar() {
state.sidebarOpen = !state.sidebarOpen
@@ -246,6 +273,7 @@ export function useAiConversations() {
archiveConversation,
setPinnedConversation,
toggleArchivedFold,
toggleGroupFold,
toggleSidebar,
}
}