重构: 前端 composable 拆分+详情页 Markdown 渲染+流式 memo+状态同步+bug 修复

- composables/useMarkdown 抽(AiChat 复用)+ai/* 流式核心+useAiSend catch 回滚 user msg(B-21)+useAiStream 超时文案(B-03)+useAiConversations 切换 token(FR-R1)
- views/TaskDetail 新建(F-02)+描述 md+mdReady 响应式+字段同行布局(B-24/31)
- views/ProjectDetail 多选审批 UI(F-01)+描述 md+mdReady+字段同行(B-25/31)
- views/Ideas+Knowledge 描述 md+mdReady(B-25)
- views/Tasks 项目切换联动(B-29)+task 详情跳转
- components/AiChat toast 失败提示(B-20)+流式块级 memo(ARC-08)+clean UI(AR-7)+stop 兜底(AR-5)
- components/ToolCard 审批卡片可读化(AR-3)
- stores useAiStore barrel(ARC-04)+del settings mock(ARC-01)+approve options(R-PD-5)
- i18n aiTool/nav 中英对称(AR-3/9)+删 nav.decisions 死链(ARC-02)
- router /tasks/:id(F-02)+global.css selection 可见(R-260615-01)+api task detail+App 删 decisions nav
This commit is contained in:
2026-06-15 05:14:56 +08:00
parent 2de0c6ecb7
commit 80b9243528
26 changed files with 997 additions and 207 deletions

View File

@@ -19,6 +19,8 @@ const state = reactive({
title: string
description: string
options: string[]
/** F-260615-01: single(缺省)/multiple */
select_type?: 'single' | 'multiple'
} | null,
loading: false,
error: null as string | null,
@@ -244,16 +246,31 @@ function createStore() {
state.liveEvents = []
}
async function approveHumanApproval(decision: string, comment?: string) {
/**
* 发送审批响应。
* - 单选(select_type=single 或缺省):传 decision 单值,decisions 留空;
* - 多选(select_type=multiple):传 decisions 数组。
* F-260615-01: 新增 decisions/select_type 透传,与后端 IPC 签名对齐。
*/
async function approveHumanApproval(
decision: string,
comment?: string,
decisions?: string[],
) {
if (!state.pendingApproval) return
try {
// 调用 IPC 命令发送审批响应
// R-PD-5: 透传 options 闭环后端校验(options 非空时 decision 必须 ∈ options否则 IPC 报错)。
// options 来自已收到的 HumanApprovalRequest 事件 payload(IPC 无法访问节点 config)。
await invoke('approve_human_approval', {
execution_id: state.pendingApproval.execution_id,
node_id: state.pendingApproval.node_id,
decision,
comment
comment,
options: state.pendingApproval.options ?? [],
decisions: decisions ?? [],
selectType: state.pendingApproval.select_type ?? 'single', // Tauri camelCase→snake_case 自动转 select_type
})
// 清除待审批状态