mirror of
https://github.com/hellodigua/ChatLab.git
synced 2026-10-25 17:54:34 +08:00
142 lines
5.3 KiB
TypeScript
142 lines
5.3 KiB
TypeScript
/**
|
|
* 聊天记录 Preload API — 导入、迁移、Demo、合并
|
|
*
|
|
* 数据查询/分析/成员管理/SQL/NLP/偏好设置已迁移到
|
|
* Internal HTTP Server (FetchDataAdapter, FetchPreferencesAdapter 等)。
|
|
*/
|
|
import { ipcRenderer } from 'electron'
|
|
import type { ImportProgress } from '../../../../src/types/base'
|
|
|
|
interface ChatImportResult {
|
|
success: boolean
|
|
sessionId?: string
|
|
platform?: string
|
|
error?: string
|
|
importMode?: 'created' | 'incremental'
|
|
matchedBy?: 'source-session-id' | 'stable-id' | 'trailing-messages'
|
|
createReason?: 'no-match' | 'ambiguous'
|
|
newMessageCount?: number
|
|
duplicateCount?: number
|
|
diagnostics?: {
|
|
logFile: string | null
|
|
detectedFormat: string | null
|
|
messagesReceived: number
|
|
messagesWritten: number
|
|
duplicateCount: number
|
|
messagesSkipped: number
|
|
skipReasons: { noSenderId: number; noAccountName: number; invalidTimestamp: number; noType: number }
|
|
}
|
|
}
|
|
|
|
export const chatApi = {
|
|
// ==================== 数据库迁移 ====================
|
|
|
|
checkMigration: (): Promise<{
|
|
needsMigration: boolean
|
|
count: number
|
|
currentVersion: number
|
|
pendingMigrations: Array<{ version: number; userMessage: string }>
|
|
}> => ipcRenderer.invoke('chat:checkMigration'),
|
|
|
|
runMigration: (): Promise<{ success: boolean; migratedCount: number; error?: string }> =>
|
|
ipcRenderer.invoke('chat:runMigration'),
|
|
|
|
// ==================== 文件选择与导入 ====================
|
|
|
|
selectFile: (): Promise<{ filePath?: string; format?: string; error?: string } | null> =>
|
|
ipcRenderer.invoke('chat:selectFile'),
|
|
|
|
import: (filePath: string): Promise<ChatImportResult> => ipcRenderer.invoke('chat:import', filePath),
|
|
|
|
importDirectory: (dirPath: string, options?: Record<string, unknown>): Promise<ChatImportResult> =>
|
|
ipcRenderer.invoke('chat:importDirectory', dirPath, options),
|
|
|
|
detectFormat: (
|
|
filePath: string
|
|
): Promise<{ id: string; name: string; platform: string; multiChat: boolean } | null> =>
|
|
ipcRenderer.invoke('chat:detectFormat', filePath),
|
|
|
|
importWithOptions: (filePath: string, formatOptions: Record<string, unknown>): Promise<ChatImportResult> =>
|
|
ipcRenderer.invoke('chat:importWithOptions', filePath, formatOptions),
|
|
|
|
importBatch: (
|
|
batchId: string,
|
|
items: Array<{ id: string; filePath: string }>,
|
|
options?: { concurrency?: number; sessionGapThreshold?: number }
|
|
) => ipcRenderer.invoke('chat:importBatch', batchId, items, options),
|
|
|
|
cancelImportBatch: (batchId: string) => ipcRenderer.invoke('chat:cancelImportBatch', batchId),
|
|
|
|
onImportBatchProgress: (callback: (progress: Record<string, unknown>) => void) => {
|
|
const handler = (_event: Electron.IpcRendererEvent, progress: Record<string, unknown>) => callback(progress)
|
|
ipcRenderer.on('chat:importBatchProgress', handler)
|
|
return () => ipcRenderer.removeListener('chat:importBatchProgress', handler)
|
|
},
|
|
|
|
scanMultiChatFile: (
|
|
filePath: string
|
|
): Promise<{
|
|
success: boolean
|
|
chats: Array<{ index: number; name: string; type: string; id: number; messageCount: number }>
|
|
error?: string
|
|
}> => ipcRenderer.invoke('chat:scanMultiChatFile', filePath),
|
|
|
|
prepareImportSource: (filePath: string) => ipcRenderer.invoke('chat:prepareImportSource', filePath),
|
|
|
|
importPreparedChat: (
|
|
sourceId: string,
|
|
chatId: string,
|
|
options?: Record<string, unknown>
|
|
): Promise<ChatImportResult> => ipcRenderer.invoke('chat:importPreparedChat', sourceId, chatId, options),
|
|
|
|
releaseImportSource: (sourceId: string) => ipcRenderer.invoke('chat:releaseImportSource', sourceId),
|
|
|
|
getSupportedFormats: (): Promise<Array<{ id: string; name: string; platform: string; extensions: string[] }>> =>
|
|
ipcRenderer.invoke('chat:getSupportedFormats'),
|
|
|
|
onImportProgress: (callback: (progress: ImportProgress) => void) => {
|
|
const handler = (_event: Electron.IpcRendererEvent, progress: ImportProgress) => callback(progress)
|
|
ipcRenderer.on('chat:importProgress', handler)
|
|
return () => ipcRenderer.removeListener('chat:importProgress', handler)
|
|
},
|
|
|
|
// ==================== 增量导入 ====================
|
|
|
|
analyzeIncrementalImport: (
|
|
sessionId: string,
|
|
filePath: string
|
|
): Promise<{
|
|
newMessageCount: number
|
|
duplicateCount: number
|
|
totalInFile: number
|
|
platform?: string
|
|
error?: string
|
|
diagnosis?: { suggestion?: string }
|
|
}> => ipcRenderer.invoke('chat:analyzeIncrementalImport', sessionId, filePath),
|
|
|
|
incrementalImport: (
|
|
sessionId: string,
|
|
filePath: string
|
|
): Promise<{ success: boolean; newMessageCount: number; error?: string }> =>
|
|
ipcRenderer.invoke('chat:incrementalImport', sessionId, filePath),
|
|
|
|
// ==================== Demo ====================
|
|
|
|
importDemo: (
|
|
locale: string,
|
|
options?: Record<string, unknown>
|
|
): Promise<{ success: boolean; groupSessionId?: string; privateSessionIds?: string[]; error?: string }> =>
|
|
ipcRenderer.invoke('demo:downloadAndImport', locale, options),
|
|
|
|
onDemoProgress: (
|
|
callback: (progress: { stage: string; current: number; total: number; message?: string }) => void
|
|
) => {
|
|
const handler = (
|
|
_event: Electron.IpcRendererEvent,
|
|
progress: { stage: string; current: number; total: number; message?: string }
|
|
) => callback(progress)
|
|
ipcRenderer.on('demo:progress', handler)
|
|
return () => ipcRenderer.removeListener('demo:progress', handler)
|
|
},
|
|
}
|