Files
AskaEth 1b78c38bb8 feat(console): 开机自启默认关闭,服务管理窗口加手动开关
- DEFAULTS.startup.openAtLogin 与随包 config.json 默认改为 false;
  applyOpenAtLogin 只有显式 true 才注册登录项(缺省/null/false 都不注册)
- config.js 新增 updateConfig():只写回文件里已有的键 + 目标键,不把 DEFAULTS 落盘
- 主进程 setOpenAtLogin():改内存 → 写回 config.json → setLoginItemSettings,
  任一失败都回滚,返回 {ok, openAtLogin};状态快照新增 openAtLogin / openAtLoginSupported
- 渲染层:服务端状态卡片新增「开机自启」滑块(纯 CSS,无依赖),
  切换即时生效并有本地意图守卫,避免被随后到达的陈旧快照冲掉
- 文档:console/README.md 与 docs/部署指南.md 同步

注意:旧包 config.json 里已显式写 true 的用户升级后仍会自启(不悄悄改既有行为),
在窗口里关一次即可;全新安装默认不注册。
2026-09-10 00:06:59 +08:00

34 lines
1.7 KiB
JavaScript

'use strict'
const { contextBridge, ipcRenderer } = require('electron')
// 渲染层是纯静态页面,能力全部经这里白名单暴露,不开 nodeIntegration
const subscribe = (channel, callback) => {
const handler = (_event, payload) => callback(payload)
ipcRenderer.on(channel, handler)
return () => ipcRenderer.removeListener(channel, handler)
}
contextBridge.exposeInMainWorld('consoleApi', {
getStatus: () => ipcRenderer.invoke('service:get-status'),
startService: () => ipcRenderer.invoke('service:start'),
stopService: () => ipcRenderer.invoke('service:stop'),
restartService: () => ipcRenderer.invoke('service:restart'),
getLog: () => ipcRenderer.invoke('log:tail'),
clearLog: () => ipcRenderer.invoke('log:clear'),
relayoutDisplays: () => ipcRenderer.invoke('display:relayout'),
getDisplayInstances: () => ipcRenderer.invoke('display:instances-get'),
setOpenAtLogin: (enabled) => ipcRenderer.invoke('startup:set-open-at-login', enabled),
openServerAdmin: () => ipcRenderer.invoke('app:open-server-admin'),
resetAdminAccount: (payload) => ipcRenderer.invoke('account:reset', payload),
minimize: () => ipcRenderer.invoke('window:minimize'),
maximize: () => ipcRenderer.invoke('window:maximize'),
close: () => ipcRenderer.invoke('window:close'),
isMaximized: () => ipcRenderer.invoke('window:is-maximized'),
onMaximizeChange: (callback) => subscribe('window:maximize-changed', callback),
onAccountOutput: (callback) => subscribe('account:output', callback),
onDisplayInstances: (callback) => subscribe('display:instances', callback),
onLog: (callback) => subscribe('log:line', callback),
onStatus: (callback) => subscribe('service:status', callback)
})