From 9ac427646504c29bd15ceb1d76caf955370f100f Mon Sep 17 00:00:00 2001 From: digua Date: Wed, 13 May 2026 19:46:41 +0800 Subject: [PATCH] refactor(adapters): replace window.chatApi calls with QueryAdapter Phase 3.0.3: Systematically replace all data-query window.chatApi calls across 24 files with getAdapter() from the new adapter layer. Replaced categories: - Session CRUD (getSessions, getSession, deleteSession, renameSession) - Statistics (getMemberActivity, getHourlyActivity, getDailyActivity, getWeekdayActivity, getMessageTypeDistribution, getAvailableYears) - Member management (getMembers, getMembersPaginated, updateMemberAliases, mergeMembers, deleteMember, getMemberNameHistory) - Social analysis (getMentionAnalysis, getLaughAnalysis, getCatchphraseAnalysis, getLanguagePreferenceAnalysis, getRelationshipStats) - SQL Lab (executeSQL, getSchema) Remaining window.chatApi calls are Electron-specific operations (import, migration, file dialog, demo, export) that will be handled separately with IS_ELECTRON guards in future phases. Also adds initAdapter() call in App.vue onMounted to bootstrap the adapter before any data loading occurs. --- src/App.vue | 3 +++ src/components/AIChat/input/AIChatInput.vue | 3 ++- src/components/DebugTab/TableBrowser.vue | 5 +++-- src/components/MessageExport/ConditionPanel.vue | 5 +++-- .../analysis/Overview/OverviewIdentityCard.vue | 3 ++- src/components/analysis/SQLLab/SchemaPanel.vue | 3 ++- src/components/analysis/SQLLabTab.vue | 3 ++- src/components/analysis/quotes/CatchphraseTab.vue | 3 ++- src/components/analysis/quotes/KeywordAnalysis.vue | 5 ++--- .../analysis/quotes/LanguagePreferenceTab.vue | 3 ++- src/components/analysis/quotes/SharedTopicsCard.vue | 3 ++- .../Settings/DataStorage/SessionIndexSection.vue | 3 ++- src/components/common/TimeSelect.vue | 6 ++++-- src/components/common/UserSelect.vue | 3 ++- src/components/common/member/MemberList.vue | 13 +++++++------ src/composables/useSessionAnalysisPageBase.ts | 12 +++++++----- .../components/member/NicknameHistory.vue | 7 +++---- .../group-chat/components/view/Relationships.vue | 3 ++- src/pages/home/components/DemoImportButton.vue | 3 ++- src/pages/home/components/ImportArea.vue | 3 ++- src/pages/private-chat/components/MemberTab.vue | 7 ++++--- .../components/view/RelationshipView.vue | 3 ++- src/stores/aiChat.ts | 3 ++- src/stores/session.ts | 9 +++++---- 24 files changed, 69 insertions(+), 45 deletions(-) diff --git a/src/App.vue b/src/App.vue index 4342bf10..ebeb1788 100644 --- a/src/App.vue +++ b/src/App.vue @@ -13,6 +13,7 @@ import { useSessionStore } from '@/stores/session' import { useLayoutStore } from '@/stores/layout' import { useSettingsStore } from '@/stores/settings' import { useLLMStore } from '@/stores/llm' +import { initAdapter } from '@/adapters' const { t } = useI18n() @@ -58,6 +59,8 @@ onMounted(async () => { // 初始化语言设置(同步 i18n 和 dayjs,异步加载脱敏规则) await settingsStore.initLocale() + // 初始化数据访问适配器(Electron / Web 自动选择) + await initAdapter() // 初始化 LLM 配置(预加载,避免首次使用时延迟) llmStore.init() // 从数据库加载会话列表 diff --git a/src/components/AIChat/input/AIChatInput.vue b/src/components/AIChat/input/AIChatInput.vue index da30680f..4fe9a58f 100644 --- a/src/components/AIChat/input/AIChatInput.vue +++ b/src/components/AIChat/input/AIChatInput.vue @@ -7,6 +7,7 @@ import SlashCommandMenu from './SlashCommandMenu.vue' import { useSkillStore, type SkillSummary } from '@/stores/skill' import type { MentionedMemberContext } from '@/composables/useAIChat' import type { MemberWithStats } from '@/types/analysis' +import { getAdapter } from '@/adapters' const { t } = useI18n() @@ -157,7 +158,7 @@ async function loadMentionMembers() { isLoadingMentionMembers.value = true try { - const members = await window.chatApi.getMembers(props.sessionId) + const members = await getAdapter().getMembers(props.sessionId) mentionMembers.value = [...members].sort((a, b) => b.messageCount - a.messageCount) } catch (error) { console.error('加载 AI @ 成员列表失败:', error) diff --git a/src/components/DebugTab/TableBrowser.vue b/src/components/DebugTab/TableBrowser.vue index 2924b6ca..bc4d9e79 100644 --- a/src/components/DebugTab/TableBrowser.vue +++ b/src/components/DebugTab/TableBrowser.vue @@ -2,6 +2,7 @@ import { ref, computed, watch, onMounted } from 'vue' import { useI18n } from 'vue-i18n' import type { TableSchema, SQLResult } from '@/components/analysis/SQLLab' +import { getAdapter } from '@/adapters' import { getColumnLabel } from '@/components/analysis/SQLLab' import type { LocaleType } from '@/i18n/types' import { UITabs } from '@/components/UI' @@ -95,7 +96,7 @@ async function runSQL(sql: string): Promise { if (dbSource.value === 'ai') { return await window.aiApi.executeAiSQL(sql) } - return await window.chatApi.executeSQL(props.sessionId, sql) + return await getAdapter().executeSQL(props.sessionId, sql) } async function loadSchema() { @@ -103,7 +104,7 @@ async function loadSchema() { if (dbSource.value === 'ai') { schema.value = await window.aiApi.getAiSchema() } else { - schema.value = await window.chatApi.getSchema(props.sessionId) + schema.value = await getAdapter().getSchema(props.sessionId) } if (sortedSchema.value.length > 0) { const defaultTable = isAiDb.value ? 'ai_message' : sortedSchema.value[0].name diff --git a/src/components/MessageExport/ConditionPanel.vue b/src/components/MessageExport/ConditionPanel.vue index 0d916fa1..342daf65 100644 --- a/src/components/MessageExport/ConditionPanel.vue +++ b/src/components/MessageExport/ConditionPanel.vue @@ -8,6 +8,7 @@ import { ref, computed, onMounted, watch } from 'vue' import { useI18n } from 'vue-i18n' import { useSessionStore } from '@/stores/session' import type { MemberWithStats } from '@/types/analysis' +import { getAdapter } from '@/adapters' import Tabs from '@/components/UI/Tabs.vue' const { t } = useI18n() @@ -66,7 +67,7 @@ async function loadMembers() { isLoadingMembers.value = true try { - members.value = await window.chatApi.getMembers(sessionId) + members.value = await getAdapter().getMembers(sessionId) } catch (error) { console.error('加载成员失败:', error) } finally { @@ -80,7 +81,7 @@ async function loadTimeRange() { if (!sessionId) return try { - const range = await window.chatApi.getTimeRange(sessionId) + const range = await getAdapter().getTimeRange(sessionId) if (range) { dbTimeRange.value = range } diff --git a/src/components/analysis/Overview/OverviewIdentityCard.vue b/src/components/analysis/Overview/OverviewIdentityCard.vue index 24cc11a7..65128f15 100644 --- a/src/components/analysis/Overview/OverviewIdentityCard.vue +++ b/src/components/analysis/Overview/OverviewIdentityCard.vue @@ -2,6 +2,7 @@ import { computed, ref, watch, onMounted, onUnmounted } from 'vue' import { useI18n } from 'vue-i18n' import { useDark } from '@vueuse/core' +import { getAdapter } from '@/adapters' import * as echarts from 'echarts/core' import { HeatmapChart, CustomChart } from 'echarts/charts' import { CalendarComponent, TooltipComponent, VisualMapComponent } from 'echarts/components' @@ -37,7 +38,7 @@ const weekdayActivity = ref([]) async function loadWeekdayActivity() { if (!props.session.id) return try { - weekdayActivity.value = await window.chatApi.getWeekdayActivity(props.session.id, props.timeFilter) + weekdayActivity.value = await getAdapter().getWeekdayActivity(props.session.id, props.timeFilter) } catch (error) { console.error('加载星期活跃度失败:', error) } diff --git a/src/components/analysis/SQLLab/SchemaPanel.vue b/src/components/analysis/SQLLab/SchemaPanel.vue index 2f38e6f8..affff4b9 100644 --- a/src/components/analysis/SQLLab/SchemaPanel.vue +++ b/src/components/analysis/SQLLab/SchemaPanel.vue @@ -2,6 +2,7 @@ import { ref, onMounted } from 'vue' import { useI18n } from 'vue-i18n' import type { TableSchema } from './types' +import { getAdapter } from '@/adapters' import { getTableLabel, getColumnLabel } from './types' import type { LocaleType } from '@/i18n/types' @@ -25,7 +26,7 @@ const expandedTables = ref>(new Set()) // 加载 Schema async function loadSchema() { try { - schema.value = await window.chatApi.getSchema(props.sessionId) + schema.value = await getAdapter().getSchema(props.sessionId) // 默认展开所有表 schema.value.forEach((table) => expandedTables.value.add(table.name)) } catch (err) { diff --git a/src/components/analysis/SQLLabTab.vue b/src/components/analysis/SQLLabTab.vue index 2c8f7273..b12affc2 100644 --- a/src/components/analysis/SQLLabTab.vue +++ b/src/components/analysis/SQLLabTab.vue @@ -3,6 +3,7 @@ import { ref, onMounted, watch } from 'vue' import { useI18n } from 'vue-i18n' import { SchemaPanel, AIHistoryModal, ResultTable, getTableLabel, getColumnLabel } from './SQLLab' import type { AIHistory, SQLResult, TableSchema } from './SQLLab' +import { getAdapter } from '@/adapters' const { t, locale } = useI18n() @@ -97,7 +98,7 @@ async function executeSQL() { resultTableRef.value?.resetSort() try { - result.value = await window.chatApi.executeSQL(props.sessionId, sql.value) + result.value = await getAdapter().executeSQL(props.sessionId, sql.value) } catch (err: any) { error.value = err.message || String(err) } finally { diff --git a/src/components/analysis/quotes/CatchphraseTab.vue b/src/components/analysis/quotes/CatchphraseTab.vue index 3389cafc..c8740604 100644 --- a/src/components/analysis/quotes/CatchphraseTab.vue +++ b/src/components/analysis/quotes/CatchphraseTab.vue @@ -2,6 +2,7 @@ import { ref, watch, computed, defineAsyncComponent } from 'vue' import { useI18n } from 'vue-i18n' import type { CatchphraseAnalysis } from '@/types/analysis' +import { getAdapter } from '@/adapters' const EChartWordcloud = defineAsyncComponent(() => import('@/components/charts/EChartWordcloud.vue')) import type { EChartWordcloudData } from '@/components/charts' import { LoadingState, EmptyState, UITabs } from '@/components/UI' @@ -96,7 +97,7 @@ async function loadCatchphraseAnalysis() { if (!props.sessionId) return isLoading.value = true try { - catchphraseAnalysis.value = await window.chatApi.getCatchphraseAnalysis(props.sessionId, props.timeFilter) + catchphraseAnalysis.value = await getAdapter().getCatchphraseAnalysis(props.sessionId, props.timeFilter) console.log( '[CatchphraseTab] API result: members:', catchphraseAnalysis.value?.members.length, diff --git a/src/components/analysis/quotes/KeywordAnalysis.vue b/src/components/analysis/quotes/KeywordAnalysis.vue index c70a455a..22425671 100644 --- a/src/components/analysis/quotes/KeywordAnalysis.vue +++ b/src/components/analysis/quotes/KeywordAnalysis.vue @@ -2,6 +2,7 @@ import { computed, ref, watch } from 'vue' import { useI18n } from 'vue-i18n' import type { LaughAnalysis, KeywordTemplate as BaseKeywordTemplate } from '@/types/analysis' +import { getAdapter } from '@/adapters' import { ListPro } from '@/components/charts' import type { RankItem } from '@/components/charts' import { LoadingState } from '@/components/UI' @@ -304,9 +305,7 @@ async function loadAnalysis() { isLoading.value = true try { - analysis.value = await window.chatApi.getLaughAnalysis(props.sessionId, props.timeFilter, [ - ...currentKeywords.value, - ]) + analysis.value = await getAdapter().getLaughAnalysis(props.sessionId, props.timeFilter, [...currentKeywords.value]) } catch (error) { console.error('加载词频分析失败:', error) analysis.value = null diff --git a/src/components/analysis/quotes/LanguagePreferenceTab.vue b/src/components/analysis/quotes/LanguagePreferenceTab.vue index 17888d3f..65d3fe21 100644 --- a/src/components/analysis/quotes/LanguagePreferenceTab.vue +++ b/src/components/analysis/quotes/LanguagePreferenceTab.vue @@ -2,6 +2,7 @@ import { ref, watch, computed } from 'vue' import { useI18n } from 'vue-i18n' import type { LanguagePreferenceResult } from '@/types/quotes/languagePreference' +import { getAdapter } from '@/adapters' import { LoadingState, EmptyState } from '@/components/UI' import { useLayoutStore } from '@/stores/layout' import LanguagePreferenceCard from './LanguagePreferenceCard.vue' @@ -28,7 +29,7 @@ async function loadData() { if (!props.sessionId) return isLoading.value = true try { - data.value = await window.chatApi.getLanguagePreferenceAnalysis(props.sessionId, locale.value, props.timeFilter) + data.value = await getAdapter().getLanguagePreferenceAnalysis(props.sessionId, locale.value, props.timeFilter) } catch (error) { console.error('[LanguagePreferenceTab] Failed to load:', error) } finally { diff --git a/src/components/analysis/quotes/SharedTopicsCard.vue b/src/components/analysis/quotes/SharedTopicsCard.vue index 728b2134..428cad9a 100644 --- a/src/components/analysis/quotes/SharedTopicsCard.vue +++ b/src/components/analysis/quotes/SharedTopicsCard.vue @@ -5,6 +5,7 @@ import { ThemeCard } from '@/components/UI' import { useSettingsStore } from '@/stores/settings' import type { SharedWord } from '@/types/quotes/languagePreference' import type { MemberWithStats } from '@/types/analysis' +import { getAdapter } from '@/adapters' import type { TimeFilter } from '@openchatlab/shared-types' const { t } = useI18n() @@ -48,7 +49,7 @@ async function loadSharedWords() { try { if (memberList.value.length === 0) { - memberList.value = await window.chatApi.getMembers(props.sessionId) + memberList.value = await getAdapter().getMembers(props.sessionId) } const topTwo = [...memberList.value].sort((a, b) => b.messageCount - a.messageCount).slice(0, 2) if (topTwo.length < 2) { diff --git a/src/components/common/Settings/DataStorage/SessionIndexSection.vue b/src/components/common/Settings/DataStorage/SessionIndexSection.vue index 48a63ac7..21bfa14d 100644 --- a/src/components/common/Settings/DataStorage/SessionIndexSection.vue +++ b/src/components/common/Settings/DataStorage/SessionIndexSection.vue @@ -5,6 +5,7 @@ */ import { ref, onMounted, computed } from 'vue' import { useI18n } from 'vue-i18n' +import { getAdapter } from '@/adapters' const { t } = useI18n() @@ -61,7 +62,7 @@ async function loadSessionIndexStatus() { isLoadingSessionStatus.value = true try { // 获取所有会话 - const sessions = await window.chatApi.getSessions() + const sessions = await getAdapter().getSessions() // 获取每个会话的索引状态 const statusList: SessionIndexStatus[] = [] diff --git a/src/components/common/TimeSelect.vue b/src/components/common/TimeSelect.vue index 2306ae7c..fa33a441 100644 --- a/src/components/common/TimeSelect.vue +++ b/src/components/common/TimeSelect.vue @@ -3,6 +3,7 @@ import { ref, computed, watch, onMounted } from 'vue' import { useI18n } from 'vue-i18n' import dayjs from 'dayjs' import { formatDateRange } from '@/utils' +import { getAdapter } from '@/adapters' import UITabs from '@/components/UI/Tabs.vue' import DatePicker from '@/components/UI/DatePicker.vue' @@ -378,9 +379,10 @@ async function loadData() { } try { + const adapter = getAdapter() const [years, range] = await Promise.all([ - window.chatApi.getAvailableYears(props.sessionId), - window.chatApi.getTimeRange(props.sessionId), + adapter.getAvailableYears(props.sessionId), + adapter.getTimeRange(props.sessionId), ]) availableYears.value = years fullTimeRange.value = range diff --git a/src/components/common/UserSelect.vue b/src/components/common/UserSelect.vue index cc10682d..fe855006 100644 --- a/src/components/common/UserSelect.vue +++ b/src/components/common/UserSelect.vue @@ -2,6 +2,7 @@ import { ref, computed, watch } from 'vue' import { useI18n } from 'vue-i18n' import type { MemberWithStats } from '@/types/analysis' +import { getAdapter } from '@/adapters' const { t } = useI18n() @@ -53,7 +54,7 @@ async function loadMembers() { if (!props.sessionId) return isLoading.value = true try { - const result = await window.chatApi.getMembers(props.sessionId) + const result = await getAdapter().getMembers(props.sessionId) // 按消息数排序 members.value = result.sort((a, b) => b.messageCount - a.messageCount) } catch (error) { diff --git a/src/components/common/member/MemberList.vue b/src/components/common/member/MemberList.vue index 658180d4..c4f63660 100644 --- a/src/components/common/member/MemberList.vue +++ b/src/components/common/member/MemberList.vue @@ -3,6 +3,7 @@ import { ref, computed, watch, onMounted } from 'vue' import { useI18n } from 'vue-i18n' import type { MemberWithStats } from '@/types/analysis' import OwnerSelector from '@/components/analysis/member/OwnerSelector.vue' +import { getAdapter } from '@/adapters' const { t } = useI18n() @@ -90,13 +91,13 @@ async function loadMembers() { if (!props.sessionId) return isLoading.value = true try { - const result = await window.chatApi.getMembersPaginated(props.sessionId, { + const result = await getAdapter().getMembersPaginated(props.sessionId, { page: currentPage.value, pageSize, search: searchQuery.value.trim(), sortOrder: sortOrder.value, }) - members.value = result.members + members.value = result.items total.value = result.total totalPages.value = result.totalPages } catch (error) { @@ -110,7 +111,7 @@ async function loadMembers() { async function loadAllMembers() { if (!props.sessionId) return try { - allMembers.value = await window.chatApi.getMembers(props.sessionId) + allMembers.value = await getAdapter().getMembers(props.sessionId) } catch (error) { console.error('加载所有成员失败:', error) } @@ -128,7 +129,7 @@ async function updateAliases(member: MemberWithStats, newAliases: string[]) { savingAliasesId.value = member.id try { - const success = await window.chatApi.updateMemberAliases(props.sessionId, member.id, aliasesToSave) + const success = await getAdapter().updateMemberAliases(props.sessionId, member.id, aliasesToSave) if (success) { // 更新本地数据 - 找到对应成员并更新 const idx = members.value.findIndex((m) => m.id === member.id) @@ -161,7 +162,7 @@ async function confirmDelete() { if (!deletingMember.value) return isDeleting.value = true try { - const success = await window.chatApi.deleteMember(props.sessionId, deletingMember.value.id) + const success = await getAdapter().deleteMember(props.sessionId, deletingMember.value.id) if (success) { // 重新加载当前页数据 await loadMembers() @@ -201,7 +202,7 @@ async function confirmMerge() { if (!mergePlan.value) return isMerging.value = true try { - const success = await window.chatApi.mergeMembers( + const success = await getAdapter().mergeMembers( props.sessionId, mergePlan.value.primary.id, mergePlan.value.secondary.id diff --git a/src/composables/useSessionAnalysisPageBase.ts b/src/composables/useSessionAnalysisPageBase.ts index 767945f2..ac971780 100644 --- a/src/composables/useSessionAnalysisPageBase.ts +++ b/src/composables/useSessionAnalysisPageBase.ts @@ -6,6 +6,7 @@ import type { MemberActivity, HourlyActivity, DailyActivity } from '@/types/anal import { useI18n } from 'vue-i18n' import { formatLocalizedDate } from '@/utils' import { useTimeSelect } from './useTimeSelect' +import { getAdapter } from '@/adapters' interface UseSessionAnalysisPageBaseOptions { route: RouteLocationNormalizedLoaded @@ -64,7 +65,7 @@ export function useSessionAnalysisPageBase(options: UseSessionAnalysisPageBaseOp if (!currentSessionId.value) return try { - const sessionData = await window.chatApi.getSession(currentSessionId.value) + const sessionData = await getAdapter().getSession(currentSessionId.value) session.value = sessionData } catch (error) { console.error('加载基础数据失败:', error) @@ -79,11 +80,12 @@ export function useSessionAnalysisPageBase(options: UseSessionAnalysisPageBaseOp try { const filter = timeFilter.value + const adapter = getAdapter() const [members, hourly, daily, types] = await Promise.all([ - window.chatApi.getMemberActivity(currentSessionId.value, filter), - window.chatApi.getHourlyActivity(currentSessionId.value, filter), - window.chatApi.getDailyActivity(currentSessionId.value, filter), - window.chatApi.getMessageTypeDistribution(currentSessionId.value, filter), + adapter.getMemberActivity(currentSessionId.value, filter), + adapter.getHourlyActivity(currentSessionId.value, filter), + adapter.getDailyActivity(currentSessionId.value, filter), + adapter.getMessageTypeDistribution(currentSessionId.value, filter), ]) memberActivity.value = members diff --git a/src/pages/group-chat/components/member/NicknameHistory.vue b/src/pages/group-chat/components/member/NicknameHistory.vue index 24d34d59..79417cfc 100644 --- a/src/pages/group-chat/components/member/NicknameHistory.vue +++ b/src/pages/group-chat/components/member/NicknameHistory.vue @@ -2,6 +2,7 @@ import { ref, watch, onMounted } from 'vue' import { useI18n } from 'vue-i18n' import type { MemberWithStats, MemberNameHistory } from '@/types/analysis' +import { getAdapter } from '@/adapters' import { SectionCard, EmptyState, LoadingState } from '@/components/UI' import { formatPeriod } from '@/utils' @@ -34,7 +35,7 @@ function getDisplayName(member: MemberWithStats): string { async function loadMembers() { if (!props.sessionId) return try { - members.value = await window.chatApi.getMembers(props.sessionId) + members.value = await getAdapter().getMembers(props.sessionId) } catch (error) { console.error('加载成员列表失败:', error) } @@ -47,9 +48,7 @@ async function loadMembersWithNicknameChanges() { const membersWithChanges: MemberWithHistory[] = [] try { - const historyPromises = members.value.map((member) => - window.chatApi.getMemberNameHistory(props.sessionId, member.id) - ) + const historyPromises = members.value.map((member) => getAdapter().getMemberNameHistory(props.sessionId, member.id)) const allHistories = await Promise.all(historyPromises) diff --git a/src/pages/group-chat/components/view/Relationships.vue b/src/pages/group-chat/components/view/Relationships.vue index 7dbb5925..64299ee6 100644 --- a/src/pages/group-chat/components/view/Relationships.vue +++ b/src/pages/group-chat/components/view/Relationships.vue @@ -2,6 +2,7 @@ import { computed, ref, watch } from 'vue' import { useI18n } from 'vue-i18n' import type { MentionAnalysis, MemberMentionDetail } from '@/types/analysis' +import { getAdapter } from '@/adapters' import { RankListPro } from '@/components/charts' import type { RankItem } from '@/components/charts' import { SectionCard, EmptyState, LoadingState } from '@/components/UI' @@ -24,7 +25,7 @@ async function loadMentionAnalysis() { if (!props.sessionId) return isLoadingMention.value = true try { - mentionAnalysis.value = await window.chatApi.getMentionAnalysis(props.sessionId, props.timeFilter) + mentionAnalysis.value = await getAdapter().getMentionAnalysis(props.sessionId, props.timeFilter) } catch (error) { console.error('加载 @ 互动分析失败:', error) } finally { diff --git a/src/pages/home/components/DemoImportButton.vue b/src/pages/home/components/DemoImportButton.vue index 28c53619..be20d956 100644 --- a/src/pages/home/components/DemoImportButton.vue +++ b/src/pages/home/components/DemoImportButton.vue @@ -5,6 +5,7 @@ import { useI18n } from 'vue-i18n' import { useSessionStore } from '@/stores/session' import { useSettingsStore } from '@/stores/settings' import { getChatlabSiteLocalePath } from '@/utils/chatlabSiteLocale' +import { getAdapter } from '@/adapters' const { t } = useI18n() const router = useRouter() @@ -16,7 +17,7 @@ const stage = ref<'downloading' | 'importing'>('downloading') const error = ref(null) async function navigateToSession(sessionId: string) { - const session = await window.chatApi.getSession(sessionId) + const session = await getAdapter().getSession(sessionId) if (session) { const routeName = session.type === 'private' ? 'private-chat' : 'group-chat' router.push({ name: routeName, params: { id: sessionId } }) diff --git a/src/pages/home/components/ImportArea.vue b/src/pages/home/components/ImportArea.vue index dc2825d2..abb2cec4 100644 --- a/src/pages/home/components/ImportArea.vue +++ b/src/pages/home/components/ImportArea.vue @@ -9,6 +9,7 @@ import { useRouter } from 'vue-router' import { useI18n } from 'vue-i18n' import { getChatlabSiteLocalePath } from '@/utils/chatlabSiteLocale' import { useSessionStore, type BatchFileInfo, type MergeFileInfo } from '@/stores/session' +import { getAdapter } from '@/adapters' import DemoImportButton from './DemoImportButton.vue' const { t } = useI18n() @@ -102,7 +103,7 @@ function translateError(error: string): string { // 根据会话类型导航到对应页面 async function navigateToSession(sessionId: string) { - const session = await window.chatApi.getSession(sessionId) + const session = await getAdapter().getSession(sessionId) if (session) { const routeName = session.type === 'private' ? 'private-chat' : 'group-chat' router.push({ name: routeName, params: { id: sessionId } }) diff --git a/src/pages/private-chat/components/MemberTab.vue b/src/pages/private-chat/components/MemberTab.vue index 05ed35dd..298f22c0 100644 --- a/src/pages/private-chat/components/MemberTab.vue +++ b/src/pages/private-chat/components/MemberTab.vue @@ -3,6 +3,7 @@ import { ref, computed, watch, onMounted } from 'vue' import { useI18n } from 'vue-i18n' import type { MemberWithStats } from '@/types/analysis' import OwnerSelector from '@/components/analysis/member/OwnerSelector.vue' +import { getAdapter } from '@/adapters' const { t } = useI18n() @@ -71,7 +72,7 @@ async function loadMembers() { if (!props.sessionId) return isLoading.value = true try { - members.value = await window.chatApi.getMembers(props.sessionId) + members.value = await getAdapter().getMembers(props.sessionId) } catch (error) { console.error('加载成员列表失败:', error) } finally { @@ -89,7 +90,7 @@ async function updateAliases(member: MemberWithStats, newAliases: string[]) { savingAliasesId.value = member.id try { - const success = await window.chatApi.updateMemberAliases(props.sessionId, member.id, aliasesToSave) + const success = await getAdapter().updateMemberAliases(props.sessionId, member.id, aliasesToSave) if (success) { const idx = members.value.findIndex((m) => m.id === member.id) if (idx !== -1) { @@ -129,7 +130,7 @@ async function confirmMerge() { if (!mergePlan.value) return isMerging.value = true try { - const success = await window.chatApi.mergeMembers( + const success = await getAdapter().mergeMembers( props.sessionId, mergePlan.value.primary.id, mergePlan.value.secondary.id diff --git a/src/pages/private-chat/components/view/RelationshipView.vue b/src/pages/private-chat/components/view/RelationshipView.vue index b0d591ec..f5a75ebe 100644 --- a/src/pages/private-chat/components/view/RelationshipView.vue +++ b/src/pages/private-chat/components/view/RelationshipView.vue @@ -2,6 +2,7 @@ import { ref, computed, watch } from 'vue' import { useI18n } from 'vue-i18n' import type { RelationshipStats, RelationshipMonthStats } from '@/types/analysis' +import { getAdapter } from '@/adapters' import { ThemeCard, SectionCard, EmptyState, LoadingState } from '@/components/UI' import { EChart } from '@/components/charts' import RelationshipMetricCard from './RelationshipMetricCard.vue' @@ -31,7 +32,7 @@ async function loadData(options?: { localOnly?: 'perseverance' }) { isLoading.value = true } try { - stats.value = await window.chatApi.getRelationshipStats(props.sessionId, props.timeFilter, { + stats.value = await getAdapter().getRelationshipStats(props.sessionId, props.timeFilter, { perseveranceThreshold: perseveranceThreshold.value, }) } catch (error) { diff --git a/src/stores/aiChat.ts b/src/stores/aiChat.ts index 50c91c66..5bc53626 100644 --- a/src/stores/aiChat.ts +++ b/src/stores/aiChat.ts @@ -10,6 +10,7 @@ import { storeToRefs } from 'pinia' import { usePromptStore } from '@/stores/prompt' import { useSessionStore } from '@/stores/session' import { useSettingsStore } from '@/stores/settings' +import { getAdapter } from '@/adapters' import { useAssistantStore } from '@/stores/assistant' import { useSkillStore } from '@/stores/skill' import type { TokenUsage, AgentRuntimeStatus, SerializedErrorInfo } from '@electron/shared/types' @@ -348,7 +349,7 @@ export const useAIChatStore = defineStore('aiChatRuntime', () => { } try { - const members = await window.chatApi.getMembers(state.sessionId) + const members = await getAdapter().getMembers(state.sessionId) const ownerMember = members.find((member) => member.platformId === ownerId) state.ownerInfo = ownerMember ? { diff --git a/src/stores/session.ts b/src/stores/session.ts index d12e7888..82322e73 100644 --- a/src/stores/session.ts +++ b/src/stores/session.ts @@ -1,6 +1,7 @@ import { defineStore } from 'pinia' import { ref, computed } from 'vue' import type { AnalysisSession, ImportProgress, ChatType } from '@/types/base' +import { getAdapter } from '@/adapters' /** 侧边栏筛选类型 */ export type SessionFilterType = 'all' | ChatType @@ -160,7 +161,7 @@ export const useSessionStore = defineStore( */ async function loadSessions() { try { - const list = await window.chatApi.getSessions() + const list = await getAdapter().getSessions() sessions.value = list // 如果当前选中的会话不存在了,清除选中状态 if (currentSessionId.value && !list.find((s) => s.id === currentSessionId.value)) { @@ -639,7 +640,7 @@ export const useSessionStore = defineStore( */ async function deleteSession(id: string): Promise { try { - const success = await window.chatApi.deleteSession(id) + const success = await getAdapter().deleteSession(id) if (success) { const index = sessions.value.findIndex((s) => s.id === id) if (index !== -1) { @@ -662,7 +663,7 @@ export const useSessionStore = defineStore( */ async function renameSession(id: string, newName: string): Promise { try { - const success = await window.chatApi.renameSession(id, newName) + const success = await getAdapter().renameSession(id, newName) if (success) { const session = sessions.value.find((s) => s.id === id) if (session) { @@ -688,7 +689,7 @@ export const useSessionStore = defineStore( */ async function updateSessionOwnerId(id: string, ownerId: string | null): Promise { try { - const success = await window.chatApi.updateSessionOwnerId(id, ownerId) + const success = await getAdapter().updateSessionOwnerId(id, ownerId) if (success) { const session = sessions.value.find((s) => s.id === id) if (session) {