server: 平台抽象层+bilibili、服务端加密凭据库、角色中间件;web: 精简页面/路由、macOS 客户端(Swift)与多份方案文档;移除误入库的编译产物

This commit is contained in:
Qiufeng
2026-08-21 10:53:32 +08:00
parent 0daa9782c9
commit 3585c39bab
103 changed files with 5842 additions and 3197 deletions
+30 -7
View File
@@ -1,4 +1,4 @@
const { app, BrowserWindow, Tray, Menu, ipcMain, shell, nativeImage } = require('electron');
const { app, BrowserWindow, Tray, Menu, Notification, ipcMain, shell, nativeImage } = require('electron');
const { spawn } = require('child_process');
const path = require('path');
const fs = require('fs');
@@ -17,6 +17,7 @@ let localJsonTimer = null;
let quitting = false;
const dataDir = path.join(app.getPath('userData'), 'data');
const localJsonPath = path.join(dataDir, 'local.json');
const coreBin = isWin ? 'agent-core.exe' : 'agent-core';
const coreExe = app.isPackaged
? path.join(process.resourcesPath, coreBin)
@@ -30,7 +31,14 @@ function startCore() {
}
fs.mkdirSync(dataDir, { recursive: true });
try { coreProc?.kill(); } catch (e) { /* ignore */ }
corePort = 0;
coreToken = '';
try { fs.rmSync(localJsonPath, { force: true }); } catch (e) { /* ignore */ }
coreProc = spawn(coreExe, ['-dir', dataDir], { windowsHide: true });
coreProc.on('error', (err) => {
console.error('[core] process error: ' + err.message);
win?.webContents.send('core-error', '核心程序启动失败:' + err.message);
});
coreProc.on('exit', (code) => {
coreProc = null;
win?.webContents.send('core-exit', code);
@@ -42,7 +50,7 @@ function pollLocalJson() {
if (localJsonTimer) clearInterval(localJsonTimer);
localJsonTimer = setInterval(() => {
try {
const info = JSON.parse(fs.readFileSync(path.join(dataDir, 'local.json'), 'utf8'));
const info = JSON.parse(fs.readFileSync(localJsonPath, 'utf8'));
if (info.port && info.token) {
corePort = info.port;
coreToken = info.token;
@@ -91,20 +99,31 @@ ipcMain.handle('core:save-config', (e, cfg) => { writeConfig(cfg); startCore();
ipcMain.handle('core:restart', () => { startCore(); return true; });
ipcMain.handle('app:open-data-dir', () => shell.openPath(dataDir));
ipcMain.handle('app:open-web', (e, url) => shell.openExternal(url));
ipcMain.handle('app:notify', (e, title, body) => {
if (Notification.isSupported()) {
new Notification({ title: String(title || 'EveryPublish'), body: String(body || '') }).show();
}
return true;
});
ipcMain.handle('app:set-autostart', (e, on) => {
app.setLoginItemSettings({ openAtLogin: !!on });
app.setLoginItemSettings({ openAtLogin: !!on, openAsHidden: true, args: ['--minimized'] });
return app.getLoginItemSettings().openAtLogin;
});
ipcMain.handle('app:get-autostart', () => app.getLoginItemSettings().openAtLogin);
ipcMain.handle('app:quit', () => { quitting = true; app.quit(); });
function readConfig() {
try { return JSON.parse(fs.readFileSync(path.join(dataDir, 'config.json'), 'utf8')); }
catch (e) { return { server: '', fakeAll: false }; }
const defaults = {
server: 'http://127.0.0.1:8090',
webUrl: 'http://127.0.0.1:3003',
fakeAll: false,
};
try { return { ...defaults, ...JSON.parse(fs.readFileSync(path.join(dataDir, 'config.json'), 'utf8')) }; }
catch (e) { return defaults; }
}
function writeConfig(cfg) {
fs.mkdirSync(dataDir, { recursive: true });
fs.writeFileSync(path.join(dataDir, 'config.json'), JSON.stringify(cfg, null, 2));
fs.writeFileSync(path.join(dataDir, 'config.json'), JSON.stringify({ ...readConfig(), ...cfg }, null, 2), { mode: 0o600 });
}
function createTray() {
@@ -172,6 +191,10 @@ async function runSmoke() {
}
}
app.on('before-quit', () => { quitting = true; try { coreProc?.kill(); } catch (e) { /* ignore */ } });
app.on('before-quit', () => {
quitting = true;
if (localJsonTimer) clearInterval(localJsonTimer);
try { coreProc?.kill(); } catch (e) { /* ignore */ }
});
app.on('window-all-closed', () => { /* 驻留托盘不退出 */ });
app.on('activate', showWin);