Files
Scoreboard/console/main/platform.js
T
AskaEth efa049c827 feat(platform): Console 支持 Linux(arm64),Windows 行为逐字不变;版本 dev_0.5.10
需求:让积分榜能在飞腾 D2000(ARM64)的 Linux 上跑起来,**同时不破坏 Windows**。

## 一、Go 服务端:交叉编译即可(**已实测**)
- SQLite 用的是 `modernc.org/sqlite`(纯 Go 驱动),全项目**没有一处 `import "C"`** → `CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build` 直接出;
- 产物是**静态链接**(`ELF 64-bit LSB executable, ARM aarch64, statically linked`)→ **不依赖 glibc 版本**,对国产系统友好;
- 本机(arm64)**实际启动验证**:数据目录、局域网地址探测、数据库迁移(0001/0002/0003)全部正常;
- 产物:`debug/服务端-arm64/scoreboard`(29 MB,`-s -w`)。

## 二、Console(Electron 宿主):平台差异收口到一个新文件
- **新增 `console/main/platform.js`**:平台差异集中在这 45 行里,其余代码不写平台判断。
  ⚠️ **`platform` 参数缺省按 Windows 解析** —— 漏传参数走的就是改动前那条老路(这比"改了再小心"更保守:**默认行为不变,新行为必须显式传参**)。
- `userpaths.js` / `datadir.js`:Windows 分支 `%LOCALAPPDATA%\ScoreboardConsole\` **逐字保留**;Linux 分支按 XDG(`$XDG_DATA_HOME`,缺省 `~/.local/share`)。两平台各自的"拿不到用户目录"提示文案分开写(免得现场去设一个本平台不存在的环境变量)。
- `config.js`:服务端文件名按平台取(Windows `scoreboard.exe` / Linux `scoreboard`)。
- **新增 `console/main/autostart.js`**:Linux 用 `~/.config/autostart/*.desktop`(开=写文件、关=删文件;Linux 没有"已注册但未启用"这个中间态)。
- 托盘与窗口行为:Linux 的通知区多数不派发 double-click,因此按平台分支成单击。

## 三、怎么保证没弄坏 Windows
1. **设计上**:平台差异集中 + 缺省值就是 Windows(见上);
2. **逐行核对 diff**:Windows 分支那几行原样未动;
3. **测试**:Console 由 **68 → 96 例**,新增全是平台分支用例,**既有断言一条没改**;
4. **真机验证**:构建机重打 Windows 包并跑(这一道才算收口)。

## 四、自检
全量自检两轮**全绿、`EXIT=0`**:服务端 14 包 / 前端 **944 例** / Console **96 例**。

## 版本
`dev_0.5.9` → **`dev_0.5.10`**;安装器素材同步重生成(照例只动 `brand.bmp` 两张)。
2026-09-15 00:53:16 +08:00

46 lines
2.3 KiB
JavaScript
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.
'use strict'
const path = require('path')
// 平台差异集中在这一个文件里:用户数据的基座目录、服务端可执行文件名、XDG 的两个目录。
// platform 与 env 一样是**入参**(缺省按 Windows 解析 —— 这是这些函数改动前就有的口径),
// 生产调用点传 process.platform / process.env;纯函数才能把两个平台都断言一遍。
// 默认值刻意不写 process.platform:否则同一份调用在不同机器上解析出不同结果,
// 测试与现场会各跑一套,Windows 分支也没法被钉住。
// 用户数据那一级目录的名字。它原来叫 LOCAL_BASE(Windows 上就挂在 %LOCALAPPDATA% 下),
// Linux 上挂在 $XDG_DATA_HOME 下,名字本身与平台无关,所以改成中性一点的名字。
const APP_DIR_NAME = 'ScoreboardConsole'
// 服务端可执行文件名:Windows 是 scoreboard.exe,Linux(飞腾 D2000 上的 linux/arm64 静态
// 编译产物)没有后缀。写死一个名字必然有一边找不到程序。
function serverExeName(platform) {
return (platform || 'win32') === 'win32' ? 'scoreboard.exe' : 'scoreboard'
}
function readEnv(env, name) {
const value = env ? env[name] : ''
return typeof value === 'string' ? value.trim() : ''
}
// XDG 规范:$XDG_DATA_HOME 必须是绝对路径,没设 / 空 / 相对路径时一律退回 ~/.local/share。
// 两个都拿不到时返回 null,由调用方回落到安装目录 —— 与 Windows 上拿不到 %LOCALAPPDATA%
// 时同一套处理(宁可让现场看见一条警告,也不猜一个路径)。
function xdgDataHome(env) {
const xdg = readEnv(env, 'XDG_DATA_HOME')
if (xdg && path.isAbsolute(xdg)) return xdg
const home = readEnv(env, 'HOME')
// HOME 也要求绝对路径:拼出来的相对路径会随进程的工作目录变,比没有更糟
return home && path.isAbsolute(home) ? path.join(home, '.local', 'share') : null
}
// 同一套规格的 $XDG_CONFIG_HOME / ~/.config:开机自启的 .desktop 放在它的 autostart/ 下
function xdgConfigHome(env) {
const xdg = readEnv(env, 'XDG_CONFIG_HOME')
if (xdg && path.isAbsolute(xdg)) return xdg
const home = readEnv(env, 'HOME')
return home && path.isAbsolute(home) ? path.join(home, '.config') : null
}
module.exports = { APP_DIR_NAME, serverExeName, xdgDataHome, xdgConfigHome }