重构: 前端DRY(style全局沉淀 + ts/js公共沉淀)

style-dry:
- 新增 src/styles/components.css: .info-item*/.panel/.panel-header/.tech-tag/.card-tags 全局
- main.ts 注册 import
- 删重复: ProjectDetail/TaskDetail/TaskOutputCard/ProjectCard/Projects(scoped删重复, 全局对子组件生效)
- 未使用清理: Projects .card-progress dead(1处保守核对)

tsjs-dry:
- aiShared.ts: resolveAiLang(合并useAiSend.resolveLang + useAiContext.resolveLanguage)
- stores/knowledge.ts: kindText/kindLabel/kindIcon/knowledgeStatusLabel/knowledgeConfidenceLabel(5公共)
- 删重复: useAiSend/useAiContext(resolveLang) + Knowledge/KnowledgeDetail(4+5 helper) + ActiveProjectsPanel(formatLastActivity→formatRelativeZh复用)

strategy: DRY收口, 公共沉淀(utils/store/shared); relativeTime非纯重复保留; .btn/.empty-hint局部override WATCH未动
This commit is contained in:
lxy
2026-06-19 12:11:19 +08:00
parent 64ece1d3a0
commit 7748e3ecbc
14 changed files with 177 additions and 212 deletions
+3 -19
View File
@@ -24,15 +24,13 @@
//! 耦合:
//! - aiApi.clearContext / aiApi.compressContext(IPC)
//! - state.activeConversationId(读当前对话)
//! - appSettings.get(df-ai-language/df-language)(压缩语言;与 useAiSend.sendMessage 同源)
//! - resolveAiLang(压缩语言;与 useAiSend.sendMessage 同源,实现在 aiShared)
import { ref } from 'vue'
import { listen, type UnlistenFn } from '@tauri-apps/api/event'
import { aiApi } from '@/api'
import { useAppSettingsStore } from '@/stores/appSettings'
import { state } from '@/stores/ai'
const appSettings = useAppSettingsStore()
import { resolveAiLang } from './aiShared'
/// 压缩中 loading(防重复点击;AiCompressing→true / AiCompressed|AiError→false)
const isCompressing = ref(false)
@@ -108,20 +106,6 @@ function stopContextListener(): void {
_callbacks = {}
}
/**
* 解析压缩语言(与 useAiSend.sendMessage 同源逻辑):
* - df-ai-language='auto' → df-language(应用主语言)
* - 否则用 df-ai-language 指定值
* - 兜底 'zh-CN'
*/
function resolveLanguage(): string {
const raw = appSettings.get<string>('df-ai-language', 'auto')
if (raw === 'auto') {
return appSettings.get<string>('df-language', 'zh-CN')
}
return raw
}
/**
* 压缩当前对话上下文。
*
@@ -136,7 +120,7 @@ async function compressContext(): Promise<void> {
if (isCompressing.value) return // 防重复点击
isCompressing.value = true
try {
await aiApi.compressContext(convId, resolveLanguage())
await aiApi.compressContext(convId, resolveAiLang())
// 后端 IPC 同步等到 LLM 压缩完成才 resolve(非 spawn 异步),成功即复位 isCompressing;
// case 'AiCompressed' 事件也复位(双保险,防事件丢失致按钮永久禁用)
isCompressing.value = false