优化: 前端u-agent令牌对齐与组件拆分续批
- 全局样式类(df-sec-h/df-toast族)替换散装实现,主题token去硬编码兜底 - 拆分子组件:ai-chat/queue-panel(队列时钟与编辑随迁)、 conversation-sidebar/ConversationList、settings/provider-panel - 父组件死副本清理(队列编辑/时钟/键位表,TS6133清零)并补 fill-draft父侧转发(重构半成品断链修复) - 验收:vue-tsc EXIT 0
This commit is contained in:
@@ -120,12 +120,12 @@
|
||||
<span v-if="typeof parsed?.encoding === 'string' && parsed.encoding !== 'utf-8'" class="ai-tool-write-meta">{{ $t('aiTool.encodingLabel', { enc: parsed.encoding }) }}</span>
|
||||
<!-- R12(2026-10-05):覆盖写入的行级 diff 回看(后端 diff 字段,新建/base64 为 null 不渲染) -->
|
||||
<div v-if="resultDiffLines.length" class="ai-tool-write-diff">
|
||||
<pre class="ai-tool-diff-pre"><code><span v-for="(ln, idx) in resultDiffLines" :key="idx" class="ai-tool-diff-line" :class="'ai-tool-diff-line--' + ln.kind">{{ ln.text }}{{ '\n' }}</span></code></pre>
|
||||
<pre class="df-diff-pre"><code><span v-for="(ln, idx) in resultDiffLines" :key="idx" class="df-diff-line" :class="'df-diff-line--' + ln.kind">{{ ln.text }}{{ '\n' }}</span></code></pre>
|
||||
<button v-if="diffTotal > DIFF_PREVIEW_LINES" type="button" class="ai-tool-diff-toggle" @click="diffExpanded = !diffExpanded">{{ diffExpanded ? $t('aiTool.diffCollapse') : $t('aiTool.diffExpand', { n: diffTotal }) }}</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- patch_file 结果:文件路径/字节增减 + unified diff 红删绿增行级预览(复用 ai-tool-diff-pre/--add/--del/--ctx 既有样式)
|
||||
<!-- patch_file 结果:文件路径/字节增减 + unified diff 红删绿增行级预览(复用 df-diff-pre/--add/--del/--ctx 样式)
|
||||
后端 generate_diff 产完整 diff,result.diff 字段此前被丢弃,用户无法验证改了什么 → 此分支渲染 diff -->
|
||||
<div v-else-if="tc.name === 'patch_file' && tc.result && tc.status === 'completed' && parsed" class="ai-tool-patch-result">
|
||||
<div class="ai-tool-file-bar">
|
||||
@@ -136,7 +136,7 @@
|
||||
</div>
|
||||
<div v-if="parsed?.warning" class="ai-tool-approval-reason"><span aria-hidden="true">⚠</span> {{ parsed.warning }}</div>
|
||||
<div v-if="resultDiffLines.length" class="ai-tool-approval-diff">
|
||||
<pre class="ai-tool-diff-pre"><code><span v-for="(ln, idx) in resultDiffLines" :key="idx" class="ai-tool-diff-line" :class="'ai-tool-diff-line--' + ln.kind">{{ ln.text }}{{ '\n' }}</span></code></pre>
|
||||
<pre class="df-diff-pre"><code><span v-for="(ln, idx) in resultDiffLines" :key="idx" class="df-diff-line" :class="'df-diff-line--' + ln.kind">{{ ln.text }}{{ '\n' }}</span></code></pre>
|
||||
<!-- R12a:长 diff 展开入口(默认预览 120 行,点开全量) -->
|
||||
<button v-if="diffTotal > DIFF_PREVIEW_LINES" type="button" class="ai-tool-diff-toggle" @click="diffExpanded = !diffExpanded">{{ diffExpanded ? $t('aiTool.diffCollapse') : $t('aiTool.diffExpand', { n: diffTotal }) }}</button>
|
||||
</div>
|
||||
@@ -468,7 +468,7 @@ watch(() => props.tc.status, (s) => {
|
||||
}
|
||||
.ai-tool-grep-match {
|
||||
padding: 3px 12px;
|
||||
border-bottom: 0.5px solid rgba(255,255,255,0.03);
|
||||
border-bottom: 0.5px solid var(--df-hover);
|
||||
}
|
||||
.ai-tool-grep-match:last-child {
|
||||
border-bottom: none;
|
||||
@@ -511,7 +511,7 @@ watch(() => props.tc.status, (s) => {
|
||||
word-break: break-all;
|
||||
background: rgba(61,219,160,0.05);
|
||||
padding: 2px 6px;
|
||||
border-radius: var(--df-radius-xs, 3px);
|
||||
border-radius: var(--df-radius-xs);
|
||||
}
|
||||
.ai-tool-grep-context {
|
||||
margin: 2px 0 0;
|
||||
@@ -521,8 +521,8 @@ watch(() => props.tc.status, (s) => {
|
||||
font-family: var(--df-font-mono);
|
||||
font-size: 10px;
|
||||
color: var(--df-text-dim);
|
||||
background: rgba(255,255,255,0.02);
|
||||
border-radius: var(--df-radius-xs, 3px);
|
||||
background: var(--df-hover);
|
||||
border-radius: var(--df-radius-xs);
|
||||
}
|
||||
.ai-tool-grep-context code {
|
||||
display: block;
|
||||
@@ -533,7 +533,7 @@ watch(() => props.tc.status, (s) => {
|
||||
font-family: var(--df-font-sans);
|
||||
font-size: 10px;
|
||||
color: var(--df-text-dim);
|
||||
background: rgba(255,255,255,0.04);
|
||||
background: var(--df-hover);
|
||||
border: 0.5px solid var(--df-border);
|
||||
border-radius: var(--df-radius-sm);
|
||||
padding: 2px 8px;
|
||||
@@ -586,13 +586,13 @@ watch(() => props.tc.status, (s) => {
|
||||
.ai-tool-dir-entry {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 7px;
|
||||
gap: 6px;
|
||||
padding: 3px 12px;
|
||||
font-size: 11px;
|
||||
transition: background 0.1s;
|
||||
}
|
||||
.ai-tool-dir-entry:hover {
|
||||
background: rgba(255,255,255,0.03);
|
||||
background: var(--df-hover);
|
||||
}
|
||||
.ai-tool-dir-entry--directory .ai-tool-dir-name {
|
||||
font-weight: 500;
|
||||
@@ -650,8 +650,8 @@ watch(() => props.tc.status, (s) => {
|
||||
padding: 4px 10px 6px;
|
||||
margin-bottom: 6px;
|
||||
font-size: 11px;
|
||||
color: var(--df-warning, #d97706);
|
||||
background: var(--df-warning-bg, rgba(217, 119, 6, 0.08));
|
||||
color: var(--df-warning);
|
||||
background: var(--df-warning-bg);
|
||||
border-radius: var(--df-radius-sm, 4px);
|
||||
}
|
||||
.ai-tool-approval-diff {
|
||||
@@ -660,29 +660,11 @@ watch(() => props.tc.status, (s) => {
|
||||
border-radius: var(--df-radius-sm, 4px);
|
||||
overflow: hidden;
|
||||
}
|
||||
.ai-tool-diff-pre {
|
||||
margin: 0;
|
||||
padding: 6px 0;
|
||||
max-height: 240px;
|
||||
overflow: auto;
|
||||
font-family: var(--df-font-mono);
|
||||
font-size: 11px;
|
||||
line-height: 1.5;
|
||||
background: var(--df-bg-card);
|
||||
}
|
||||
.ai-tool-diff-pre code {
|
||||
display: block;
|
||||
white-space: pre;
|
||||
}
|
||||
.ai-tool-diff-line {
|
||||
display: block;
|
||||
padding: 0 10px;
|
||||
white-space: pre-wrap;
|
||||
word-break: break-all;
|
||||
}
|
||||
.ai-tool-diff-line--add { color: var(--df-success, #3ddb9c); background: var(--df-success-bg, rgba(61, 219, 160, 0.08)); }
|
||||
.ai-tool-diff-line--del { color: var(--df-danger, #f06565); background: var(--df-danger-bg, rgba(240, 101, 101, 0.08)); }
|
||||
.ai-tool-diff-line--ctx { color: var(--df-text-dim, #888); }
|
||||
/* diff 基类 .df-diff-pre(+code)/.df-diff-line 消费 global.css 共享定义(2026-10-18 整洁波
|
||||
双轨合一,与 ToolCard.vue 审批 diff 同源),此处仅留行配色变体 */
|
||||
.df-diff-line--add { color: var(--df-success); background: var(--df-success-bg); }
|
||||
.df-diff-line--del { color: var(--df-danger); background: var(--df-danger-bg); }
|
||||
.df-diff-line--ctx { color: var(--df-text-dim); }
|
||||
|
||||
/* -- Generic Result --
|
||||
max-height 100px→200px:通用结果常含 JSON/结构化文本,100px 仅约 5 行,默认滚动条挤压可读性;
|
||||
@@ -741,12 +723,12 @@ watch(() => props.tc.status, (s) => {
|
||||
border-radius: var(--df-radius-sm);
|
||||
background: transparent;
|
||||
color: var(--df-text-dim);
|
||||
font-size: 10.5px;
|
||||
font-size: 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.ai-tool-cmd-toggle:hover {
|
||||
color: var(--df-text);
|
||||
background: var(--df-bg-hover, rgba(255,255,255,0.06));
|
||||
background: var(--df-hover);
|
||||
}
|
||||
.ai-tool-cmd-output {
|
||||
margin: 0;
|
||||
@@ -803,8 +785,8 @@ watch(() => props.tc.status, (s) => {
|
||||
}
|
||||
.ai-tool-http-trunc-warn {
|
||||
padding: 4px 10px;
|
||||
font-size: 10.5px;
|
||||
color: var(--df-warning, #f0c75e);
|
||||
font-size: 10px;
|
||||
color: var(--df-warning);
|
||||
border-top: 0.5px solid var(--df-border);
|
||||
}
|
||||
|
||||
@@ -828,10 +810,10 @@ watch(() => props.tc.status, (s) => {
|
||||
}
|
||||
.ai-tool-fetch-mode--static,
|
||||
.ai-tool-fetch-mode--obscura {
|
||||
color: var(--df-success, #3ddb9c);
|
||||
color: var(--df-success);
|
||||
}
|
||||
.ai-tool-fetch-mode--static_fallback {
|
||||
color: var(--df-warning, #f0c75e);
|
||||
color: var(--df-warning);
|
||||
}
|
||||
.ai-tool-fetch-title {
|
||||
padding: 4px 10px 2px;
|
||||
@@ -845,8 +827,8 @@ watch(() => props.tc.status, (s) => {
|
||||
.ai-tool-obscura-hint {
|
||||
margin: 4px 10px 6px;
|
||||
padding: 6px 8px;
|
||||
background: var(--df-warning-bg, rgba(240,199,94,0.08));
|
||||
border: 0.5px solid var(--df-warning, #f0c75e);
|
||||
background: var(--df-warning-bg);
|
||||
border: 0.5px solid var(--df-warning);
|
||||
border-radius: var(--df-radius-sm, 4px);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@@ -854,8 +836,8 @@ watch(() => props.tc.status, (s) => {
|
||||
}
|
||||
.ai-tool-obscura-hint-text {
|
||||
font-family: var(--df-font-sans);
|
||||
font-size: 10.5px;
|
||||
color: var(--df-warning, #f0c75e);
|
||||
font-size: 10px;
|
||||
color: var(--df-warning);
|
||||
line-height: 1.5;
|
||||
word-break: break-word;
|
||||
}
|
||||
@@ -870,7 +852,7 @@ watch(() => props.tc.status, (s) => {
|
||||
font-weight: 500;
|
||||
border-radius: var(--df-radius-sm, 4px);
|
||||
border: none;
|
||||
background: var(--df-accent, #5b8def);
|
||||
background: var(--df-accent);
|
||||
color: #fff;
|
||||
cursor: pointer;
|
||||
font-family: var(--df-font-sans);
|
||||
@@ -891,5 +873,5 @@ watch(() => props.tc.status, (s) => {
|
||||
padding: 3px 12px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.ai-tool-diff-toggle:hover { color: var(--df-text); background: var(--df-bg-secondary); }
|
||||
.ai-tool-diff-toggle:hover { color: var(--df-text); background: var(--df-bg-card); }
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user