重构: ToolCard.vue 拆分(1167→374 行,REFACTOR-260619-04)

纯结构拆分,逻辑等价,渲染/交互/接口契约不变:
- 抽 ToolResultBody.vue(545 行,8 工具结果渲染分支:read_file/list_directory/
  search_files/write_file/patch_file/run_command/http_request/通用 CRUD)
- 抽 useToolCardRender.ts(45 行,parseDiffLines 渲染纯函数)
- 抽 useToolCardHeader.ts(154 行,toolDisplayName/displayArgValue/projectNameById 头部显示)
- ToolCard.vue 瘦身至 374 行(容器+头部+审批区+状态机,结果展示委托 ToolResultBody)
- props/emits 契约不变(ToolCardList/AiChat/MessageList 调用零改动)

vue-tsc EXIT 0 + 8/8 渲染分支完整核对
This commit is contained in:
lxy
2026-06-19 21:45:09 +08:00
parent ba47f44ab8
commit 74f38609e0
4 changed files with 844 additions and 893 deletions
+45
View File
@@ -0,0 +1,45 @@
/**
* ToolCard 渲染层纯函数辅助(从 ToolCard.vue 抽离)。
*
* 职责:diff 行解析等无状态渲染纯函数。响应式 computed/ref 仍留各自组件,
* 这里只提供「输入→输出」的确定性变换,便于单测与跨组件复用(write_file 审批 diff
* 与 patch_file 结果 diff 共用同一解析逻辑)。
*
* 注:策略表(parseResult/formatBytes/formatSizeDiff 等带语义的)仍在 useToolCard.ts,
* 本文件仅收「与模板渲染强耦合、原散落在 ToolCard.vue 内联」的纯展示函数。
*/
/** diff 行种类:增/删/上下文 */
export type DiffLineKind = 'add' | 'del' | 'ctx'
/** 一行 diff 解析结果(kind 用于模板着色,text 原样显示) */
export interface DiffLine {
kind: DiffLineKind
text: string
}
/**
* 解析 unified diff 文本 → DiffLine[]。
*
* 来源(AE-2025-03 / UX-260618-06):后端 generate_diff 输出 '+新行/-旧行/(空格)上下文',
* 逐行拆 → {kind, text} 供模板按 kind 着色(add 绿/del 红/ctx 灰)。
*
* - 空行过滤(generate_diff 末尾保留单尾换行 → split 末尾有空串元素)
* - maxLines 截断:超长 diff 截到前 N 行并追加「…」占位(防撑爆卡片);undefined 不截断
*
* 纯函数,无副作用,相同输入恒定输出。
*/
export function parseDiffLines(text: string | undefined | null, maxLines?: number): DiffLine[] {
if (!text) return []
const lines = text.split('\n').map(line => {
if (line === '') return null
if (line.startsWith('+')) return { kind: 'add' as const, text: line }
if (line.startsWith('-')) return { kind: 'del' as const, text: line }
return { kind: 'ctx' as const, text: line }
}).filter((x): x is DiffLine => x !== null)
if (maxLines !== undefined && lines.length > maxLines) {
lines.splice(maxLines)
lines.push({ kind: 'ctx', text: '…' })
}
return lines
}