优化: i18n硬编码清扫(8文件20+处中文字符串替为i18n)

- ToolCard: 已等待 → aiTool.waitTime

- ErrorBoundary: 堆栈详情 → error.stackDetails

- TopBar: 10处硬编码(tooltip+section标签+单位) → aiChat.* keys

- FileExplorer: 4处工程操作title → fileExplorer.*

- Tasks: 快捷菜单4处 → tasks.*

- EnrichmentPanel: 取消关联 → aiChat.enrichmentDismiss

- PlanProgress: 复用已有 aiChat.conflictsPending

- WorkflowDagDisplay: 删除中文fallback(已有i18n key)

- vue-tsc + vite build 通过
This commit is contained in:
lxy
2026-07-02 12:19:57 +08:00
parent 34944df764
commit 3f22fd3673
18 changed files with 78 additions and 24 deletions
+1 -1
View File
@@ -9,7 +9,7 @@
<div class="error-boundary-title">{{ $t('error.title') }}</div>
<div class="error-boundary-desc">{{ errorMessage }}</div>
<details class="error-boundary-details">
<summary>堆栈详情</summary>
<summary>{{ $t('error.stackDetails') }}</summary>
<pre class="error-boundary-stack">{{ errorStack }}</pre>
</details>
<button class="error-boundary-retry" @click="reset">{{ $t('error.retry') }}</button>
+1 -1
View File
@@ -42,7 +42,7 @@
<div v-if="tc.reason" class="ai-tool-approval-reason"> {{ tc.reason }}</div>
<!-- BUG-260624-02: 审批挂起时长提示(>2分钟橙色,>5分钟红色) -->
<div v-if="waitSecs > 0" class="ai-tool-wait-time" :class="'is-' + waitLevel">
已等待 {{ formatWaitTime(waitSecs) }}
{{ $t('aiTool.waitTime', { time: formatWaitTime(waitSecs) }) }}
</div>
<!-- AE-2025-03: write_file 审批 diff 预览(红删绿增,行级)旧文件不存在tc.diff 为空,回退显上方 args content -->
<div v-if="tc.diff" class="ai-tool-approval-diff">
+1 -1
View File
@@ -51,7 +51,7 @@ function toggleExpanded(current: boolean) {
</svg>
<span class="ai-enrichment-badge">{{ enrichmentBadgeText }}</span>
</button>
<button class="ai-enrichment-dismiss" @click="emit('dismiss')" title="取消关联">×</button>
<button class="ai-enrichment-dismiss" @click="emit('dismiss')" :title="$t('aiChat.enrichmentDismiss')">×</button>
<div v-if="enrichmentExpanded" class="ai-enrichment-panel">
<div class="ai-enrichment-label">{{ $t('aiChat.enrichmentLabel') }}</div>
<pre class="ai-enrichment-body"><code>{{ enrichmentDetailText }}</code></pre>
+1 -1
View File
@@ -26,7 +26,7 @@
</div>
<!-- 冲突徽章 -->
<div v-if="conflicts.length > 0" class="plan-conflicts-badge" @click="emit('show-conflicts')">
{{ conflicts.length }} 处冲突待处理
{{ t('aiChat.conflictsPending', { n: conflicts.length }) }}
</div>
</div>
</template>
+10 -10
View File
@@ -113,7 +113,7 @@
<div class="ai-bottom-tools-right">
<!-- 目标计数 -->
<div v-if="goals.length" class="ai-goals-inline">
<span class="ai-goals-inline-badge ai-tool-badge" @click="goalsExpanded = !goalsExpanded" title="查看目标">
<span class="ai-goals-inline-badge ai-tool-badge" @click="goalsExpanded = !goalsExpanded" :title="$t('aiChat.viewGoals')">
<svg width="9" height="9" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><circle cx="12" cy="12" r="6"/><circle cx="12" cy="12" r="2"/></svg>
{{ goals.length }}
</span>
@@ -126,7 +126,7 @@
</div>
<!-- 历史消息 -->
<div v-if="historyMsgs.length" class="ai-history-inline">
<span class="ai-history-inline-badge ai-tool-badge" @click="historyExpanded = !historyExpanded" title="查看历史消息">
<span class="ai-history-inline-badge ai-tool-badge" @click="historyExpanded = !historyExpanded" :title="$t('aiChat.viewHistory')">
<svg width="9" height="9" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>
{{ historyMsgs.length }}
</span>
@@ -140,44 +140,44 @@
</div>
<!-- 上下文摘要 -->
<div v-if="summaryMsgs.length" class="ai-summary-inline">
<span class="ai-summary-inline-badge ai-tool-badge" @click="summaryExpanded = !summaryExpanded" title="查看上下文摘要">
<span class="ai-summary-inline-badge ai-tool-badge" @click="summaryExpanded = !summaryExpanded" :title="$t('aiChat.viewSummary')">
<svg width="9" height="9" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 6h16M4 12h16M4 18h12"/></svg>
{{ summaryMsgs.length }}
</span>
<div v-if="summaryExpanded" class="ai-summary-inline-list">
<div v-for="(s, i) in summaryMsgs" :key="i" class="ai-summary-inline-item" @click="scrollToMessage(s.id)">
<span class="ai-summary-label">{{ $t('aiChat.compressedSummaryLabel') || '上下文摘要' }} #{{ summaryMsgs.length - i }}</span>
<span class="ai-summary-label">{{ $t('aiChat.compressedSummaryLabel') }} #{{ summaryMsgs.length - i }}</span>
<p class="ai-summary-preview">{{ s.text }}</p>
</div>
</div>
</div>
<!-- L3 完整上下文 -->
<div v-if="contextInfo.goals.length || contextInfo.summaryCount > 0" class="ai-context-inline">
<span class="ai-context-inline-badge ai-tool-badge" @click="contextExpanded = !contextExpanded" title="查看 AI 上下文">
<span class="ai-context-inline-badge ai-tool-badge" @click="contextExpanded = !contextExpanded" :title="$t('aiChat.viewContext')">
<svg width="9" height="9" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><path d="M12 16v-4"/><circle cx="12" cy="8" r="1" fill="currentColor"/></svg>
</span>
<div v-if="contextExpanded" class="ai-context-inline-list">
<!-- 系统提示 -->
<div class="ai-context-section">
<div class="ai-context-section-title">系统提示</div>
<div class="ai-context-section-title">{{ $t('aiChat.contextSystemPrompt') }}</div>
<div class="ai-context-section-body">
<div class="ai-context-row">
<span class="ai-context-label">目标({{ contextInfo.goals.length }})</span>
<span class="ai-context-value">{{ contextInfo.goals.join('; ') || '无' }}</span>
</div>
<div class="ai-context-row">
<span class="ai-context-label">环境</span>
<span class="ai-context-label">{{ $t('aiChat.contextEnvironment') }}</span>
<span class="ai-context-value">{{ contextInfo.osInfo }}</span>
</div>
<div class="ai-context-row">
<span class="ai-context-label">压缩摘要</span>
<span class="ai-context-value">{{ contextInfo.summaryCount }} </span>
<span class="ai-context-label">{{ $t('aiChat.contextCompressedSummary') }}</span>
<span class="ai-context-value">{{ contextInfo.summaryCount }} {{ $t('aiChat.contextCountUnit') }}</span>
</div>
</div>
</div>
<!-- 增强上下文 -->
<div class="ai-context-section">
<div class="ai-context-section-title">增强上下文</div>
<div class="ai-context-section-title">{{ $t('aiChat.contextEnrichment') }}</div>
<div class="ai-context-section-body">
<div class="ai-context-row">
<span class="ai-context-label">@项目</span>
+4 -4
View File
@@ -45,20 +45,20 @@
</div>
<div class="toolbar-right">
<button class="btn btn-ghost btn-sm" type="button" title="编辑当前工程" @click="openEditModule">
<button class="btn btn-ghost btn-sm" type="button" :title="$t('fileExplorer.editCurrentModule')" @click="openEditModule">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"/><path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"/></svg>
</button>
<button class="btn btn-ghost btn-sm" type="button" title="删除当前工程" @click="confirmRemoveModule">
<button class="btn btn-ghost btn-sm" type="button" :title="$t('fileExplorer.deleteCurrentModule')" @click="confirmRemoveModule">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="3 6 5 6 21 6"/><path d="M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/></svg>
</button>
<button class="btn btn-ghost btn-sm" type="button" title="添加工程" @click="openAddModule">
<button class="btn btn-ghost btn-sm" type="button" :title="$t('fileExplorer.addModuleTitle')" @click="openAddModule">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg>
</button>
<button class="btn btn-ghost btn-sm" type="button" :disabled="refreshing" @click="refresh">
<span v-if="refreshing" class="spinner"></span>
{{ refreshing ? $t('fileExplorer.refreshing') : $t('fileExplorer.refresh') }}
</button>
<button class="btn btn-ghost btn-sm" type="button" title="弹出到独立窗口" @click="onDetach">
<button class="btn btn-ghost btn-sm" type="button" :title="$t('fileExplorer.detachToWindow')" @click="onDetach">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M15 3h6v6"/>
<path d="M10 14L21 3"/>
@@ -46,14 +46,14 @@
@keydown.enter="saveCondition(i)"
@keydown.escape="cancelEdit"
@blur="saveCondition(i)"
:placeholder="$t('taskDetail.workflowCondPlaceholder') || '输入条件表达式'"
:placeholder="$t('taskDetail.workflowCondPlaceholder')"
/>
<span
v-else
class="wf-dag-cond-label"
:class="{ 'wf-dag-cond-label--uncond': !edge.condition, 'wf-dag-cond-label--editable': true }"
@click="startEdit(i, edge)"
>{{ edge.condition || ($t('taskDetail.workflowUnconditional') || '无条件') }}</span>
>{{ edge.condition || $t('taskDetail.workflowUnconditional') }}</span>
</div>
</div>
</details>