Files
Scoreboard/console/README.md
T

130 lines
7.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 白名单
└── shell-preload.js # 服务端管理面板窗口的 window.desktopShell 白名单
```
## 运行方式
```bash
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` 为无限);恢复健康后自动重载大屏 |
| 关管理窗口 | 只隐藏到托盘,服务端继续运行;退出必须走托盘「退出」 |
| 窗口外观 | 管理窗口与服务端管理面板窗口都是 `frame: false` 无边框,标题栏与最小化/最大化/关闭三键由页面自绘(拖拽区 `-webkit-app-region: drag`,按钮 `no-drag`,双击标题栏切最大化,关闭键 hover 变红) |
| 服务端管理面板 | 用独立无边框 Electron 窗口加载 `http://127.0.0.1:<port>/admin`(`shell-preload.js` 暴露 `window.desktopShell`),不再调系统浏览器;面板页在浏览器里直接打开时标题栏自动不渲染 |
| 日志 | 内存环形缓冲(`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` | 管理窗口初始尺寸(服务端管理面板窗口按 `width` 不小于 1100 取用) |
| `log.maxLines` / `log.file` / `log.maxFileBytes` | `2000` / `logs/console.log` / `4194304` | 日志缓冲与文件 |
配置缺项自动用内置默认值,文件不存在或 JSON 语法错误时回落到全默认值,并在管理窗口顶部给出提示。
## 打包计划(electron-builder,尚未跑通)
`package.json` 里已写好 `build` 段:
```bash
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 安装。