优化: AI Chat 消息视图: 闪烁修复+骨架统一+过程卡降级+任务关联 chip

MessageList.vue:
1. 流式闪烁修复: _mdRenderKey 稳定化 + key 对齐, 消除流式重渲染抖动
2. 骨架统一: 过程步骤卡改用 trace 卡骨架(头部一行摘要 + 正文增量)
3. 过程卡视觉降级: 缩进收窄 + 紧贴结果, 弱化过程突出结论
4. 消息任务关联: TASK_REF_TOOLS 映射(advance_task/run_workflow) 从
   toolCalls[].args 派生任务 chip, 零数据模型改动(单一事实源), 无任务工具
   的消息不渲染 chip; 新增 .ai-trace-task-chip 样式 + go-to-task emit

AiChat.vue: goToTask(taskId) 接参, router.push('/tasks?taskId=xxx')
Tasks.vue: applyRouteTaskId 消费 query.taskId 自动开抽屉(onMounted 跨路由 +
  watch 同路由), 消费后 router.replace 清 query 保持 URL 干净
i18n zh/en: aiChat.goToTaskHint + ai.trace.taskRef 双语补键

验收: vue-tsc --noEmit EXIT 0 + build EXIT 0。
This commit is contained in:
lxy
2026-10-09 22:53:22 +08:00
parent a8c92e9619
commit 40c4a21a7e
5 changed files with 177 additions and 25 deletions
+19 -1
View File
@@ -408,7 +408,7 @@
<script setup lang="ts">
import { ref, computed, onMounted, onUnmounted, watch, reactive, nextTick } from 'vue'
import { useRouter } from 'vue-router'
import { useRouter, useRoute } from 'vue-router'
import { useI18n } from 'vue-i18n'
import { useProjectStore } from '@/stores/project'
import { formatRelative } from '@/utils/time'
@@ -426,6 +426,7 @@ import { useTaskBatchActions } from '@/composables/task/useTaskBatchActions'
import { useTaskKanban } from '@/composables/task/useTaskKanban'
const router = useRouter()
const route = useRoute()
const store = useProjectStore()
const { t } = useI18n()
const { confirmState, confirmDialog, answerConfirm } = useConfirm()
@@ -854,6 +855,21 @@ const drawerVisible = computed(() => drawerTaskId.value !== null)
function openDrawer(id: string) { drawerTaskId.value = id }
function closeDrawer() { drawerTaskId.value = null }
// 路由 query.taskId 驱动抽屉(AI Chat 消息任务 chip 点击跳转入口):
// 从 /tasks?taskId=xxx 进入时自动打开对应任务抽屉。同路由内再次跳转(已在 /tasks 页)
// 由 watch(route.query.taskId) 响应;跨路由进入由 onMounted 调用。URL 参数消费后清除,
// 避免刷新页面重复弹抽屉。
function applyRouteTaskId() {
const tid = route.query.taskId
if (typeof tid === 'string' && tid) {
openDrawer(tid)
// 消费后清除 query(taskId),保持 URL 干净;replace 不新增历史栈
const rest = { ...route.query }
delete rest.taskId
router.replace({ path: route.path, query: rest })
}
}
function buildTaskQuery(): TaskQuery | undefined {
const projAll = activeProject.value === 'all'
const kw = searchKeyword.value.trim()
@@ -988,6 +1004,8 @@ onMounted(async () => {
loading.value = false
}
if (viewMode.value === 'kanban') kanbanRefresh()
// 路由 query.taskId 驱动抽屉(AI Chat chip 跳转入口)
applyRouteTaskId()
window.addEventListener('keydown', onKeydown)
document.addEventListener('click', closeQuickMenu)
})