Files
Scoreboard/console

Scoreboard Console

赛事积分榜系统的桌面宿主(Electron)。它只做四件事:

  1. 拉起并守护同目录(或配置指定)的 scoreboard.exe,把它的 stdout/stderr 接管到管理窗口与日志文件;
  2. 用 screen.getAllDisplays() 枚举显示器,把大屏页面投到扩展屏;
  3. powerSaveBlocker.start('prevent-display-sleep') 防熄屏;
  4. 提供启动/停止/状态/日志的管理 GUI 和托盘菜单。

规范来源:devdocs/06-大屏端设计.md 第 6 节、devdocs/10-部署与现场方案.md 第 4 节。

目录结构

console/
├── package.json          # main 指向 main/index.js;electron-builder 配置
├── config.json           # 运行配置(端口 / exe 路径 / 选屏策略)
├── main/
│   ├── index.js          # 应用入口:窗口 / 托盘 / IPC / 生命周期
│   ├── config.js         # 配置加载与合并、exe 路径解析
│   ├── service.js        # 服务端子进程守护:spawn / 日志转发 / 健康检查 / 自动重启
│   ├── displays.js       # 大屏窗口管理:选屏、kiosk、排布、24h 重载
│   ├── log-bus.js        # 日志环形缓冲 + 落文件 + 广播
│   └── tray-icon.js      # 托盘图标(base64 内嵌,无外部资源文件)
└── renderer/
    ├── index.html        # 管理窗口
    ├── styles.css
    ├── app.js
    └── preload.js        # contextBridge 白名单

运行方式

cd console
npm install        # 首次需要下载 Electron
npm start          # 等价于 electron .

开发时把 scoreboard.exe 放在以下任一位置都能被找到(config.json 里的相对路径会按顺序探测):

  1. console/
  2. 当前工作目录
  3. 仓库根目录
  4. dist/

现场(部署包)形态:

scoreboard-windows-amd64/
├── Scoreboard Console.exe
├── resources/app.asar      # 内含 main/ renderer/ config.json
├── config.json             # exe 旁边的可编辑配置
├── scoreboard.exe
├── config.yaml
├── rules/
├── data/
└── logs/console.log        # 运行时生成

打包后 config.json 读取顺序:SCOREBOARD_CONSOLE_CONFIG 环境变量 → exe 同目录的 config.json。

行为说明

场景 行为
只有一块屏 窗口化(屏幕 80% 大小、居中),不做多屏编排,不挂 display-metrics-changed 等监听(行为冻结);F11 手动切换全屏
多块屏 除主屏外每块屏一个 kiosk 窗口,按 display.bounds(DIP)定位,窗口 setIgnoreMouseEvents(true),光标由页面 CSS 隐藏
选屏 运行时枚举,不写死坐标;selection 可选 all-secondary(默认)/ all / specified
页面锁定 每块屏各锁一页,URL 形如 http://127.0.0.1:8080/display?page=standings&lock=1&screen=<id>&instance=<host>-<id>,页序按 display.pages 轮转
防熄屏 Console 启动即生效,退出时释放;前台后台都算
服务端就绪 首次 /api/health 通过后开大屏窗口;等待超过 display.waitForServerMs 也先开,避免现场只见桌面
服务端崩溃 按 restartDelayMs 递增退避自动重启(maxRestarts=0 为无限);恢复健康后自动重载大屏
关管理窗口 只隐藏到托盘,服务端继续运行;退出必须走托盘「退出」
日志 内存环形缓冲(log.maxLines)+ 文件 logs/console.log(超 maxFileBytes 轮转一份 .1)

配置项(config.json)

键 默认值 说明
server.exe scoreboard.exe 相对路径按上文顺序探测,也可写绝对路径
server.args ["-config","config.yaml"] 传给服务端的参数
server.host / server.port 127.0.0.1 / 8080 健康检查与管理面板地址(0.0.0.0 会自动换成回环地址探测)
server.autoStart true Console 启动后是否立刻拉起服务端
server.healthIntervalMs 5000 健康检查间隔
server.restartDelayMs 3000 重启基础退避,每次翻倍,最多 5 倍
server.maxRestarts 0 0 = 无限重启
display.selection all-secondary all-secondary / all / specified
display.displays [] specified 时生效,填 display id 或 0 起序号
display.pages ["standings","medals","individual","results","records"] 按屏序轮转锁定
display.pageParam page 页面 URL 参数名
display.kiosk true 多屏时是否 kiosk(单屏恒窗口化)
display.ignoreMouse true 多屏窗口是否忽略鼠标
display.reloadEveryHours 24 定时重载兜底,0 = 关闭
display.waitForServerMs 20000 服务端未就绪时开大屏的兜底等待
display.backgroundColor #0b0f1a 窗口底色,减少加载白闪
admin.width / admin.height 1040 / 760 管理窗口初始尺寸
log.maxLines / log.file / log.maxFileBytes 2000 / logs/console.log / 4194304 日志缓冲与文件

配置缺项自动用内置默认值,文件不存在或 JSON 语法错误时回落到全默认值,并在管理窗口顶部给出提示。

打包计划(electron-builder,尚未跑通)

package.json 里已写好 build 段:

cd console
npm install
npm run dist     # electron-builder --win --x64 → ../dist/console/
npm run pack     # 只出目录,不生成安装包,便于现场调试
  • 产物:NSIS 安装包 + zip(Scoreboard Console-0.1.0-x64.*)。
  • extraFiles 会把 ../dist/scoreboard.exe 与 ../config.yaml 拷到安装目录,最终形成第 4 节里的部署包形态。
  • 图标资源目录 build/ 尚未提供,暂用 Electron 默认图标;补上 build/icon.ico 后自动生效。
  • 未在 Windows 构建机上实际执行过 npm run dist(本机没有安装 Electron/electron-builder,也按要求未执行 npm install)。

尚未实机验证

以下内容只做了静态语法检查,需要在 Windows + 真实多显示器环境跑一遍:

  • 多屏 kiosk 定位与 display-metrics-changed 重排(改分辨率 / 缩放 / 插拔 HDMI)。
  • powerSaveBlocker 在长时间后台下的实际效果。
  • 托盘图标在 Windows 任务栏的显示效果(16px 缩放)。
  • scoreboard.exe 真实拉起、日志转发、健康检查与崩溃重启的端到端链路。
  • electron-builder 打包与 NSIS 安装。