ssurui 6f93912c86 feat: 初始提交——elec_rag_ui 独立前端工程
基于 Electron + Vue3 + TypeScript + LanceDB 的本地化 RAG 问答桌面应用。
仅支持 Linux(Kylin V10 / Ubuntu),适配 ER160(揽月 M50 NPU)和 ER25(芯动力 RPP)计算卡。
服务进程管理委托给 er_backend(HTTP 17700),前端专注 RAG 逻辑与用户交互。

包含:
- src/elec_rag_ui 前端工程(Electron + Vue3)
- models/ 本地嵌入模型(bge-small/base/large,ASR,标点恢复,onnx 文件由 Git LFS 管理)
- docs/ 示例文档(用于测试索引与问答)
2026-08-15 19:25:28 +08:00

96 lines
3.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { contextBridge, ipcRenderer } from 'electron'
console.log('[preload] 正在注册 electronAPI...')
contextBridge.exposeInMainWorld('electronAPI', {
// 文件选择
selectFiles: (): Promise<string[]> =>
ipcRenderer.invoke('select-files'),
selectDirectory: (): Promise<string | null> =>
ipcRenderer.invoke('select-directory'),
// 入库
indexDocuments: (payload: { paths: string[]; mode: 'append' | 'rebuild' }): Promise<void> =>
ipcRenderer.invoke('index-documents', payload),
// 查询
query: (payload: { question: string; systemPrompt: string; topK: number }): Promise<void> =>
ipcRenderer.invoke('query', payload),
// 状态 & 配置
getDbStatus: (): Promise<{ count: number; ready: boolean }> =>
ipcRenderer.invoke('get-db-status'),
getConfig: () => ipcRenderer.invoke('get-config'),
saveConfig: (config: unknown) => ipcRenderer.invoke('save-config', config),
testEmbedConnection: (embedConfig: unknown): Promise<{ ok: boolean; message: string }> =>
ipcRenderer.invoke('embed-test', embedConfig),
testChatConnection: (chatConfig: unknown): Promise<{ ok: boolean; message: string }> =>
ipcRenderer.invoke('chat-test', chatConfig),
// 本地嵌入模型
selectModelDir: (): Promise<string | null> =>
ipcRenderer.invoke('select-model-dir'),
checkModelPath: (dirPath: string): Promise<boolean> =>
ipcRenderer.invoke('check-model-path', dirPath),
// 退出程序
quitApp: (): Promise<void> =>
ipcRenderer.invoke('quit-app'),
// 批量问题导入导出
importBatchQuestions: (): Promise<string[] | null> =>
ipcRenderer.invoke('batch:import'),
exportBatchQuestions: (questions: string[]): Promise<boolean> =>
ipcRenderer.invoke('batch:export', questions),
// 硬件探测
hardwareGetDetected: (): Promise<'er160' | 'er25' | 'none' | null> =>
ipcRenderer.invoke('hardware:get-detected'),
// 平台信息
platform: process.platform,
// 语音输入(ASR)
asrSelectModelDir: (): Promise<string | null> =>
ipcRenderer.invoke('asr:select-model-dir'),
asrSelectExecutable: (): Promise<string | null> =>
ipcRenderer.invoke('asr:select-executable'),
asrCheckModelDir: (dirPath: string): Promise<boolean> =>
ipcRenderer.invoke('asr:check-model-dir', dirPath),
asrInitModel: (): Promise<boolean> =>
ipcRenderer.invoke('asr:init-model'),
asrStartStream: (): Promise<boolean> =>
ipcRenderer.invoke('asr:start-stream'),
asrFeedChunk: (samples: number[]): Promise<boolean> =>
ipcRenderer.invoke('asr:feed-chunk', samples),
asrStopStream: (): Promise<string> =>
ipcRenderer.invoke('asr:stop-stream'),
asrUnloadModel: (): Promise<boolean> =>
ipcRenderer.invoke('asr:unload-model'),
// 语音输出(系统 TTS 兜底)
ttsAvailable: (): Promise<boolean> =>
ipcRenderer.invoke('tts:available'),
ttsConfigure: (options: unknown): Promise<boolean> =>
ipcRenderer.invoke('tts:configure', options),
ttsSpeak: (text: string): Promise<boolean> =>
ipcRenderer.invoke('tts:speak', text),
ttsStop: (): Promise<boolean> =>
ipcRenderer.invoke('tts:stop'),
// er-backend 管理服务(Linux NPU)
erBackendEnsure: (): Promise<{ ok: boolean; message: string }> =>
ipcRenderer.invoke('er-backend:ensure'),
erBackendStatus: (): Promise<unknown> =>
ipcRenderer.invoke('er-backend:status'),
// 事件监听(ASR/TTS 推送事件)
on: (channel: string, callback: (...args: unknown[]) => void) => {
ipcRenderer.removeAllListeners(channel)
ipcRenderer.on(channel, (_event, ...args) => callback(...args))
},
off: (channel: string) => {
ipcRenderer.removeAllListeners(channel)
}
})