优化: AI Chat 渲染与无障碍 + 文件查看 + 同步 IO 收口

- 渲染: 结果/过程分离(气泡只放最终结果,过程轮叙述+工具卡收进轨迹卡默认收起可展开——治『流式后正文消失』且不再 N 气泡打扰)
- 渲染 P0: v-memo 定向 dep(只有真正渲染流式块的 item 失效,其余取占位) + renderItems 桶 memo(签名覆盖全消费输入,item 引用稳定) + 指纹 watch 降为 O(1) toolEpoch
- TopBar 三处 O(n) messages computed 合并单次遍历;md 缓存改有界 LRU(除满即全清抖动);useTurnTrace 补 never 穷尽 + default;MessageItem 模板去重
- 无障碍(四批累计): 可点容器键盘化(含 role/tabindex/keydown/aria-expanded) + icon-only aria-label 约 60 处 + 装饰图标 aria-hidden + 52 个滚动容器 overscroll-behavior:contain + 设置开关聚焦可见环 + outline 零补偿站点补 :focus-visible
- UX 走查项: 灵感 IDEA-10/11、知识 KNOW-6/7/9、项目详情 O8、审计 SA-4、设置 SA-6/26/27/28(脏表单/冗余 save/clamp/删除二次确认)
- 文件查看专项: 切工程状态残留 F5/F6、FileTree 去重与展开反馈 F7/F15/F17、切文件头部残留 F18、R 状态着色 F19;FilePreview diff 文件头(---/+++)误当增删渲染修复 + 大纲行高亮死样式修复 + 图片失败文案 i18n 化
- 同步 IO 收口(异步上下文内阻塞): unattended 看板读写改 tokio::fs、fetch_url 探活改 spawn_blocking、http/generate_image 清理改 tokio::fs
- 子代理 P3 批量: 任务书钉扎上限/截断文案区分父子语境/环境画像日期/temperature 可覆盖/model 回退上报/lang 透传
- crate 清理: df-execute·df-types 注释与格式、df-ideas 过时注释、df-nodes subflow 夸大描述、df-project 死变量
This commit is contained in:
lxy
2026-10-10 08:09:45 +08:00
parent 8df4e33656
commit 39e0eac39d
67 changed files with 1344 additions and 364 deletions
+3 -3
View File
@@ -8,7 +8,7 @@
<div class="tbb-actions">
<!-- 推进到 ▾(仅渲染全部可达的交集目标) -->
<div class="tbb-menu" ref="advanceMenuRef">
<button class="btn btn-ghost btn-sm" :disabled="busy || advanceTargets.length === 0" @click.stop="toggleMenu('advance')">
<button class="btn btn-ghost btn-sm" :disabled="busy || advanceTargets.length === 0" :aria-expanded="activeMenu === 'advance'" @click.stop="toggleMenu('advance')">
{{ $t('tasks.batch.advanceTo') }} ▾
</button>
<div v-if="activeMenu === 'advance'" class="tbb-dropdown" @click.stop>
@@ -25,7 +25,7 @@
<!-- 改优先级 ▾ -->
<div class="tbb-menu" ref="priorityMenuRef">
<button class="btn btn-ghost btn-sm" :disabled="busy" @click.stop="toggleMenu('priority')">
<button class="btn btn-ghost btn-sm" :disabled="busy" :aria-expanded="activeMenu === 'priority'" @click.stop="toggleMenu('priority')">
{{ $t('tasks.batch.priority') }} ▾
</button>
<div v-if="activeMenu === 'priority'" class="tbb-dropdown" @click.stop>
@@ -37,7 +37,7 @@
<!-- 指派 ▾(内嵌输入 + 建议) -->
<div class="tbb-menu" ref="assigneeMenuRef">
<button class="btn btn-ghost btn-sm" :disabled="busy" @click.stop="toggleMenu('assignee')">
<button class="btn btn-ghost btn-sm" :disabled="busy" :aria-expanded="activeMenu === 'assignee'" @click.stop="toggleMenu('assignee')">
{{ $t('tasks.batch.assignee') }} ▾
</button>
<div v-if="activeMenu === 'assignee'" class="tbb-dropdown tbb-dropdown--assignee" @click.stop>
+10 -1
View File
@@ -123,7 +123,16 @@
<span class="subtask-progress-text">{{ $t('taskDetail.progressTitle') }}: {{ subtaskProgress.done }}/{{ subtaskProgress.total }}</span>
</div>
<div v-if="children.length > 0" class="subtask-list">
<div v-for="child in children" :key="child.id" class="subtask-item" @click="router.push(`/tasks/${child.id}`); $emit('close')">
<div
v-for="child in children"
:key="child.id"
class="subtask-item"
role="button"
tabindex="0"
@click="router.push(`/tasks/${child.id}`); $emit('close')"
@keydown.enter.prevent="router.push(`/tasks/${child.id}`); $emit('close')"
@keydown.space.prevent="router.push(`/tasks/${child.id}`); $emit('close')"
>
<span class="subtask-title">{{ child.title }}</span>
<span class="status-tag" :class="taskStatusClass(child.status)">{{ $t(taskStatusLabel(child.status)) }}</span>
<span class="priority-badge" :class="priorityClass(child.priority)">{{ priorityLabel(child.priority) }}</span>