重构: 前端DRY收口+后端测试类型对齐

- 新增 useToast composable: 消除 AiChat/Settings/Projects 4处 toast 重复
  统一默认3000ms(Projects原4000ms为操作类提示保留参数覆盖)
- 新增 utils/json.ts parseJsonArray: 消除 parseStack/parseTags/ModuleNode
  3处JSON字符串数组解析重复
- 新增 utils/html.ts escapeHtml: 消除 useMarkdown/FilePreview 2处重复
- ProjectDetail score-bar 内联三元改用 scoreTier(消除最后一处阈值硬编码)
- ConversationSidebar 删除 formatTime 透传包装(直接用 formatRelative)
- 清理死代码: parseTs/stringifyError/ErrorSink/_Unused 改私有或删除
  wrapNakedDiff 改私有(无外部 import)
- ModuleNode shortPath 改名 truncatedPath(与 useToolCard.shortPath 语义不同)
This commit is contained in:
lxy
2026-07-03 00:18:21 +08:00
parent 249b3b9ea8
commit 3d8b755229
22 changed files with 163 additions and 124 deletions
+3 -8
View File
@@ -2,6 +2,7 @@ import { reactive, computed } from 'vue'
import { knowledgeApi } from '@/api'
import { t } from '@/i18n/i18n-helpers'
import { runWithCatch, runWithCatchGuarded } from '@/composables/useStoreAction'
import { parseJsonArray } from '@/utils/json'
import type {
KnowledgeRecord,
KnowledgeDetailPayload,
@@ -46,14 +47,8 @@ export const KNOWLEDGE_KINDS = [
] as const
/** 解析 tags JSON 字符串为 string[] */
export function parseTags(tags: string | null): string[] {
if (!tags) return []
try {
const arr = JSON.parse(tags)
return Array.isArray(arr) ? arr : []
} catch {
return []
}
export function parseTags(tags: string | null | undefined): string[] {
return parseJsonArray(tags)
}
// ── 知识 label 文案辅助(列表 Knowledge.vue 与详情 KnowledgeDetail.vue 共用) ──