需求:让积分榜能在飞腾 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` 两张)。
46 lines
2.3 KiB
JavaScript
46 lines
2.3 KiB
JavaScript
'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 }
|