重构: 前端架构审查降技术债·i18n收口(高ROI)
- 新建 src/i18n/i18n-helpers.ts: 类型安全 t + currentLocale(any中转内部1处带注释)
- 12文件改 i18n as any 样板收口: utils/time + stores(knowledge/project/{ideas,projects,tasks,workflow}) + composables(aiShared/useAiConversations/useAiEvents/useAiSend/useAiStream/useToolCard)
- as any 22→10(i18n 13→0对外), 签名统一(key, named?)
- useToolCard文档块同步(防AI被过时注释误导)
This commit is contained in:
@@ -13,13 +13,11 @@
|
||||
import { aiApi } from '@/api'
|
||||
import { state } from '@/stores/ai'
|
||||
import { useAppSettingsStore } from '@/stores/appSettings'
|
||||
import i18n from '@/i18n'
|
||||
import { t } from '@/i18n/i18n-helpers'
|
||||
import type { AiToolCallInfo } from '@/api/types'
|
||||
|
||||
const appSettings = useAppSettingsStore()
|
||||
|
||||
const t = ((i18n as any).global.t as (k: string, named?: Record<string, unknown>) => string).bind((i18n as any).global)
|
||||
|
||||
/**
|
||||
* 解析 AI 回复语言(useAiSend.sendMessage / useAiContext.compressContext 共用)。
|
||||
*
|
||||
|
||||
@@ -10,14 +10,11 @@ import { state } from '@/stores/ai'
|
||||
import { notifyConversationChanged } from './useAiEvents'
|
||||
import { persistUiState } from './useAiPanel'
|
||||
import { nextMsgId } from './aiShared'
|
||||
import i18n from '@/i18n'
|
||||
import { t } from '@/i18n/i18n-helpers'
|
||||
import type { AiMessage, AiToolCallInfo } from '@/api/types'
|
||||
|
||||
const appSettings = useAppSettingsStore()
|
||||
|
||||
// composable 无组件上下文,借全局 i18n 实例翻译错误文案(同 useAiSend/aiShared 模式)
|
||||
const t = ((i18n as any).global.t as (k: string, named?: Record<string, unknown>) => string).bind((i18n as any).global)
|
||||
|
||||
/** 拉取会话列表;首次加载时若 appSettings 仍有有效 active-conv 且当前无活跃对话则恢复 */
|
||||
async function loadConversations() {
|
||||
try {
|
||||
|
||||
@@ -16,17 +16,12 @@ import { ref } from 'vue'
|
||||
import { aiApi } from '@/api'
|
||||
import { useAppSettingsStore } from '@/stores/appSettings'
|
||||
import { state } from '@/stores/ai'
|
||||
import i18n from '@/i18n'
|
||||
import { t } from '@/i18n/i18n-helpers'
|
||||
import { nextMsgId, findToolCall, startApprovalTimer, clearApprovalTimer, clearAllApprovalTimers } from './aiShared'
|
||||
import { resetStreamWatchdog, clearStreamWatchdog } from './useAiStream'
|
||||
import { loadConversations } from './useAiConversations'
|
||||
import type { AiChatEvent, AiMessage, AiToolCallInfo } from '@/api/types'
|
||||
|
||||
// composable 内非组件上下文(无 setup),用 vue-i18n 全局实例的 t 而非 useI18n()。
|
||||
// 通过 any 中转规避 vue-i18n 深度 message schema 泛型导致的 TS2589(类型实例化过深)。
|
||||
// CR-30-2: 签名放宽支持插值参数(复用现有 t('ai.xxx', {...}) 模式,如 aiShared.ts:75)。
|
||||
const t = ((i18n as any).global.t as (key: string, params?: Record<string, unknown>) => string).bind((i18n as any).global)
|
||||
|
||||
let _unlistenAiEvent: (() => void) | null = null
|
||||
let _unlistenConvChanged: (() => void) | null = null
|
||||
// AE-2025-06: onStreamTimeout 广播的审批计时器清理事件 unlistener
|
||||
|
||||
@@ -21,13 +21,11 @@ import { ref } from 'vue'
|
||||
import { aiApi } from '@/api'
|
||||
import { state } from '@/stores/ai'
|
||||
import type { ContentPart, AiMessage } from '@/api/types'
|
||||
import i18n from '@/i18n'
|
||||
import { t } from '@/i18n/i18n-helpers'
|
||||
import { resetStreamWatchdog, clearStreamWatchdog } from './useAiStream'
|
||||
import { startListener } from './useAiEvents'
|
||||
import { nextMsgId, findToolCall, startApprovalTimer, clearApprovalTimer, clearAllApprovalTimers, resolveAiLang } from './aiShared'
|
||||
|
||||
const t = ((i18n as any).global.t as (k: string, named?: Record<string, unknown>) => string).bind((i18n as any).global)
|
||||
|
||||
/// 待发送队列上限(超过抛错提示用户)
|
||||
const QUEUE_LIMIT = 10
|
||||
|
||||
|
||||
@@ -12,14 +12,10 @@
|
||||
//! 循环依赖;下沉到 aiShared 后本模块不再 import useAiEvents,环消除)
|
||||
|
||||
import { state } from '@/stores/ai'
|
||||
import i18n from '@/i18n'
|
||||
import { t } from '@/i18n/i18n-helpers'
|
||||
import { nextMsgId } from './aiShared'
|
||||
import { emit } from '@tauri-apps/api/event'
|
||||
|
||||
// composable 内非组件上下文(无 setup),用 vue-i18n 全局实例的 t 而非 useI18n()。
|
||||
// 通过 any 中转规避 vue-i18n 深度 message schema 泛型导致的 TS2589(类型实例化过深)。
|
||||
const t = ((i18n as any).global.t as (key: string) => string).bind((i18n as any).global)
|
||||
|
||||
/// ≥ 后端 STREAM_IDLE_TIMEOUT(120s, ai.rs:848)+余量;
|
||||
/// 前端若短于后端,慢首 token 会被前端先误杀
|
||||
export const STREAM_TIMEOUT_MS = 130000
|
||||
|
||||
@@ -11,22 +11,18 @@
|
||||
//! 及原 <script setup> 中仅依赖 i18n.t 的 toolResultSummary)。零行为变更,纯搬迁。
|
||||
//!
|
||||
//! 设计:
|
||||
//! - composable 内非组件上下文(无 setup),用 vue-i18n 全局实例的 t(对齐 aiShared.ts/
|
||||
//! useAiEvents.ts/useAiStream.ts 等同款约定),而非 useI18n()。
|
||||
//! - 非组件上下文(无 setup),用 @/i18n/i18n-helpers 的类型安全 t(规避 vue-i18n TS2589)。
|
||||
//! - 全部为纯函数(入参出参,无响应式无副作用),供 ToolCard.vue 模板/setup 直接 import 调用。
|
||||
//! - store 依赖的工具显示名(toolDisplayName/displayArgValue/projectNameById/taskNameById)
|
||||
//! 仍留 ToolCard.vue setup(耦合 projectStore,非纯函数)。
|
||||
//!
|
||||
//! 耦合:
|
||||
//! - i18n.global.t(翻译)
|
||||
//! - i18n 翻译(经 @/i18n/i18n-helpers)
|
||||
//! - AiToolCallInfo(@/api/types)
|
||||
|
||||
import i18n from '@/i18n'
|
||||
import { t } from '@/i18n/i18n-helpers'
|
||||
import type { AiToolCallInfo } from '@/api/types'
|
||||
|
||||
// composable 内非组件上下文(无 setup),用 vue-i18n 全局实例的 t 而非 useI18n()。
|
||||
const t = ((i18n as any).global.t as (k: string, p?: Record<string, unknown>) => string).bind((i18n as any).global)
|
||||
|
||||
/** 工具结果 JSON 已知字段(全可选;list_* 运行时返回数组,靠 Array.isArray 区分) */
|
||||
export interface ToolResult {
|
||||
path?: string
|
||||
|
||||
Reference in New Issue
Block a user