// config.js —— 后端各服务地址配置的读写(主进程)。 // 设置文件 userData/config.json 形如 { services: { bff, qa, rag, legacy, vstore, paper, bioflow } }。 // 每个地址都可指向本机或其它服务器。功能上桌面端反代只走 bff(BFF 是前端 /api/* 的唯一入口, // 由 BFF 内部再路由到 qa/rag/vstore/paper/bioflow——见 README)。 // 环境变量 PLANTAI_BFF_URL 覆盖 bff(供脚本/CI 用)。 const fs = require('fs'); const path = require('path'); const DEFAULT_SERVICES = { bff: 'http://127.0.0.1:8090', // BFF 总入口(前端 /api/* 的唯一入口) qa: 'http://127.0.0.1:8091', // QA 问答(qa_base_url) rag: 'http://127.0.0.1:8092', // 方法学 RAG(rag_base_url) legacy: 'http://127.0.0.1:8093', // 旧版 RAG(rag_legacy_base_url) vstore: 'http://127.0.0.1:8094', // 文档向量库(vstore_base_url) paper: 'http://127.0.0.1:8097', // 论文撰写(paper_writer_url) bioflow: 'http://127.0.0.1:8098', // 生信 bioflow(bioflow_service_url) }; const SERVICE_KEYS = Object.keys(DEFAULT_SERVICES); function normalizeUrl(url) { return String(url || '').trim().replace(/\/+$/, ''); } function configPath(userDataDir) { return path.join(userDataDir, 'config.json'); } function loadServices(userDataDir) { const services = { ...DEFAULT_SERVICES }; // 设置文件覆盖默认 try { const raw = fs.readFileSync(configPath(userDataDir), 'utf8'); const cfg = JSON.parse(raw); const saved = (cfg && cfg.services) || {}; for (const k of SERVICE_KEYS) { const v = normalizeUrl(saved[k]); if (v) services[k] = v; } } catch (_e) { // 无配置文件或解析失败 → 落到默认 } // 环境变量最高优先级,最后覆盖 bff const envBff = normalizeUrl(process.env.PLANTAI_BFF_URL); if (envBff) services.bff = envBff; return services; } function saveServices(userDataDir, services) { fs.mkdirSync(userDataDir, { recursive: true }); const out = {}; for (const k of SERVICE_KEYS) { const v = normalizeUrl(services && services[k]); out[k] = v || DEFAULT_SERVICES[k]; } fs.writeFileSync(configPath(userDataDir), JSON.stringify({ services: out }, null, 2), 'utf8'); return out; } module.exports = { loadServices, saveServices, DEFAULT_SERVICES, SERVICE_KEYS };