优化: 所有剩余UI/UX待办一批完成(持久化+AuditLog+解耦+total+原12大改+P2)

持久化(P1-c):新建 usePersistedRef composable,Tasks/AuditLog/ProjectDetail 等接入 localStorage

AuditLog(P1-d):后端 list_tool_executions 加 WHERE 筛选+返 {items,total,has_more},前端对接+长列折叠+筛选持久化

数据源解耦(P1-g):ProjectDetail projectTasks 按 project_id 独立加载 + ChatInput @项目联想独立加载(不读 store.tasks 当前页)

GitChanges(12a):后端 get_module_commits 加 git rev-list --count 返 total,前端显真实总数

原12大改:Dashboard 统计卡压底行(1)/Projects 列表卡片视图(2)/project_event 埋点排序(3)/TaskDetail 重设计(4)/IdeaDetail 重设计(5)/KnowledgeDetail 重设计(6)/界面持久化+侧栏Ctrl+B+审批数字键(7)/ProjectDetail 三栏改两栏(10)

P2打磨:文件浏览器(FileTree去重/FilePreview行号.md Diff/selectedFilePath归位)/settings反馈(假保存/端口校验)/AI会话(try-catch/scrollIntoView)/后端计数(move_queue事件/timeline total/workflow分页/import_batch分块)/杂项(TopBar/ConfirmDialog键盘/CIStatus i18n/ToolResultBody/ModuleNode/ApprovalDialog全选)
This commit is contained in:
lxy
2026-08-02 13:11:06 +08:00
parent caaabf0c15
commit f736f435bc
70 changed files with 2645 additions and 576 deletions
+24 -4
View File
@@ -53,8 +53,14 @@
<button class="ai-btn-icon" @click="emit('new-conversation')" :title="$t('aiChat.newConversation')">
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M12 20h9"/><path d="M16.5 3.5a2.121 2.121 0 013 3L7 19l-4 1 1-4L16.5 3.5z"/></svg>
</button>
<!-- 清空对话(真删 DB messages,带二次确认防误删)。高频常用,常驻。 -->
<button class="ai-btn-icon" @click="emit('clear-chat')" :title="$t('aiChat.clearChat')">
<!-- 清空对话(真删 DB messages,带二次确认防误删)。高频常用,常驻。
disabled:无活跃消息(空会话)或流式中(避免并发删/写),对齐 clear-context 项语义。 -->
<button
class="ai-btn-icon"
:disabled="!hasActiveMessages || store.state.streaming"
:title="$t('aiChat.clearChat')"
@click="emit('clear-chat')"
>
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><polyline points="3 6 5 6 21 6"/><path d="M19 6l-1 14a2 2 0 01-2 2H8a2 2 0 01-2-2L5 6"/><path d="M10 11v6"/><path d="M14 11v6"/><path d="M9 6V4a1 1 0 011-1h4a1 1 0 011 1v2"/></svg>
</button>
@@ -391,8 +397,22 @@ const historyExpanded = ref(false)
/** 点击历史消息项 → 滚动定位到对应的消息气泡 */
function scrollToMessage(msgId: string) {
historyExpanded.value = false
// 消息列表已有 data-msg-id 属性,直接 DOM 查询定位
const el = document.querySelector(`[data-msg-id="${msgId}"]`)
// 消息列表已有 data-msg-id 属性,直接 DOM 查询定位。
// BUG-260802:msgId 由后端生成,可能含 CSS 选择器元字符(: . [ ] / 空格 等),
// 模板拼 selector 会被选择器解析器当伪类/类名异常 → querySelector 抛错或返回 null。
// 用 CSS.escape 转义 msgId,确保任意字符串安全嵌入属性选择器。
// 旧浏览器无 CSS.escape 的兜底:encodeURIComponent + attr*= 模糊匹配(非精确,降级路径)。
let el: Element | null = null
const escaped = typeof CSS !== 'undefined' && typeof CSS.escape === 'function'
? CSS.escape(msgId)
: encodeURIComponent(msgId)
try {
el = document.querySelector(`[data-msg-id="${escaped}"]`)
} catch {
// 转义后仍异常(理论不会)→ 退化为遍历查找
const all = document.querySelectorAll('[data-msg-id]')
el = Array.from(all).find(n => n.getAttribute('data-msg-id') === msgId) ?? null
}
if (el) {
el.scrollIntoView({ behavior: 'smooth', block: 'center' })
}