mirror of
https://wget.la/https://github.com/Wxw-Gu/WechatExplorer
synced 2026-10-06 05:27:48 +08:00
让 WechatExplorer 既能用图形界面浏览聊天记录,也能作为本机 MCP 数据源被
Claude / Codex 等客户端通过 127.0.0.1:6131 直接拉取。
本机 HTTP API
- 新增 http-server: 8 个端点,覆盖 health / current_time / contact /
chatroom / recent_chat / chatlog / group_snapshot / resolve / report
- 时间参数支持 YYYY-MM-DD / YYYY-MM-DD/HH:mm / Unix 秒级;日期单独使用
时自动补到 00:00:00~23:59:59,避免漏消息
- apiServer 单例支持动态启停,启动失败返回 friendlyMessage(把
EADDRINUSE 翻译成"端口已被占用"的中文错误并附 4 次重试)
数据库根目录与自服务入口
- Wcdb4Client 接受 accountRoot 时会自动解析:父目录下找最新含
db_storage 的 wxid 子目录;设置面板"测试连接"成功后回写解析后的
精确路径
- 抽 chat-service.ts:IPC 和 HTTP 共享 listContacts / listMessages /
getGroupSnapshot / searchMessages / getSelfAccountInfo / testConnection
/ reopenWithRoot
- WechatDb 接受可选 accountRoot;设置面板新增"应用并重新初始化"
按钮,改完 dbRoot 立即生效
- 新增 settings-store.ts,dbRoot / apiEnabled / apiHost / apiPort 落到
userData/settings.json
主进程健壮性
- 新增 safe-log.ts 包一层 console.log/warn/error,electron-vite 关闭
子进程 stderr 后写 EPIPE 不再炸 IPC handler(原 main build 启动时
即 installSafeConsole)
76 lines
1.7 KiB
TypeScript
76 lines
1.7 KiB
TypeScript
import { app } from 'electron'
|
|
import fs from 'fs-extra'
|
|
import path from 'path'
|
|
import os from 'os'
|
|
|
|
export interface AppSettings {
|
|
dbRoot: string
|
|
apiEnabled: boolean
|
|
apiHost: string
|
|
apiPort: number
|
|
}
|
|
|
|
const DEFAULT_SETTINGS: AppSettings = {
|
|
dbRoot: path.join(
|
|
os.homedir(),
|
|
'Library/Containers/com.tencent.xinWeChat/Data/Documents/xwechat_files'
|
|
),
|
|
apiEnabled: true,
|
|
apiHost: '127.0.0.1',
|
|
apiPort: 6131
|
|
}
|
|
|
|
const SETTINGS_FILE = path.join(
|
|
process.env['WE_SETTINGS_DIR'] || app.getPath('userData'),
|
|
'settings.json'
|
|
)
|
|
|
|
let cache: AppSettings | null = null
|
|
|
|
function ensureDir(): void {
|
|
fs.ensureDirSync(path.dirname(SETTINGS_FILE))
|
|
}
|
|
|
|
export function loadSettings(): AppSettings {
|
|
if (cache) return cache
|
|
try {
|
|
if (fs.existsSync(SETTINGS_FILE)) {
|
|
const raw = fs.readJsonSync(SETTINGS_FILE) as Partial<AppSettings>
|
|
cache = { ...DEFAULT_SETTINGS, ...raw }
|
|
return cache
|
|
}
|
|
} catch (error) {
|
|
console.warn('[Settings] failed to load, fallback to defaults:', error)
|
|
}
|
|
cache = { ...DEFAULT_SETTINGS }
|
|
return cache
|
|
}
|
|
|
|
export function saveSettings(next: AppSettings): AppSettings {
|
|
cache = { ...next }
|
|
try {
|
|
ensureDir()
|
|
fs.writeJsonSync(SETTINGS_FILE, cache, { spaces: 2 })
|
|
} catch (error) {
|
|
console.error('[Settings] failed to save:', error)
|
|
}
|
|
return cache
|
|
}
|
|
|
|
export function updateSettings(patch: Partial<AppSettings>): AppSettings {
|
|
return saveSettings({ ...loadSettings(), ...patch })
|
|
}
|
|
|
|
export function resetSettings(): AppSettings {
|
|
cache = null
|
|
try {
|
|
if (fs.existsSync(SETTINGS_FILE)) fs.unlinkSync(SETTINGS_FILE)
|
|
} catch {
|
|
// best effort
|
|
}
|
|
return loadSettings()
|
|
}
|
|
|
|
export function getSettingsPath(): string {
|
|
return SETTINGS_FILE
|
|
} |