feat(import): 报名模板按「小项 × 组别」分工作表;号码布判重改认证件号;备份改原子落盘

三件事合成一次提交(其中两件都落在 handlers_config.go,无法按文件拆开):

一、分工作表报名模板(新增能力)
- 新增 GET /api/entries/template.xlsx:按当前赛事的「小项 × 组别」生成模板,
  一个小项组别一张工作表,工作表名 = <小项>@<组别>(31 字符上限、重名自动去重)。
- 导入解析器认工作表名还原小项 + 组别;若与表内列冲突则报错,不静默取其一。
- 小项名与组别名禁用 @,基础数据界面 / 规则包导入 / 服务端校验三处一并拦截。
- 单表 CSV/XLSX 导入路径不回归。

二、号码布判重(修误判)
- 旧逻辑依赖证件号本身,而证件号是可选字段 → 同一个人报多个项目会被整块拦下。
- 改为:号码布相同且证件号相同 → 判定为同一人报多项,放行;
  号码布相同且证件号都能填且不同 → 仍报错(真抢号);一方证件号为空 → 放行并给提示。
- 团体行的号码布一并纳入查重。

三、自动备份的关停与落盘(修数据安全隐患)
- export.Service 增加 Wait():StartAuto 的协程进 WaitGroup,关停时 join(10 秒上限,
  超时只记 WARN 不拖死关闭),不再在备份写到一半时退出。
- vacuumInto 改为先写 <最终名>.tmp-<随机> 再 rename,失败则删临时文件;
  Backup / SafetySnapshot / ExportProjectZip 三个调用方一并受益。
- 新增 isFinalBackupName,ListBackups / safetyCopies / KindOfBackupName 统一过滤中间文件,
  避免半截 .db 被列进备份列表、进而被「一键恢复」选中。

文档:docs/ 五份(使用手册 / 报名名单导入规范 / 升级说明 / 部署指南 / 上线检查清单)同步。
This commit is contained in:
AskaEth committed 2026-09-14 01:10:16 +08:00
1 parent b74768b7d5
commit 1b8a37ff8c
32 files changed
+3302 -233

No files matched your search

+13 -8
View File
@@ -48,12 +48,15 @@ deploy\build.bat
### 3.1 使用安装包
1. 双击 `Scoreboard Console-<版本>-x64.exe`(版本以 `dist\console\` 下实际文件名为准)。
2. 按向导选择安装目录(可自定义)。
3. 安装完成后,桌面会出现名为**「赛事积分榜」**的快捷方式。
1. 双击 `Scoreboard Console-<版本>-x64.exe`(版本以 `dist\console\` 下实际文件名为准)。**安装程序一启动就会申请管理员权限**:Windows 会先弹一次 UAC(「是否允许此应用对你的设备进行更改?」),点「是」。**受限账户(不是管理员)的机器不会弹** —— 它拿不到「为所有用户」那一档,安装程序会自动降级为「仅为我安装」(见第 2 步)。
2. 按向导选**装法与安装目录**:
- **「为所有用户安装」**(新版默认):装到 `C:\Program Files\Scoreboard_Console`,并在这一趟**自动放行防火墙入站 19540**(防火墙里能看到规则 `Scoreboard Console (TCP 19540)`,卸载时自动删掉)。**升级时不用手工关掉旧版本** —— 安装程序会自己找到并关闭在跑的旧版本(含它拉起的 `scoreboard.exe` 服务端进程),见 3.4。
- **「仅为我安装」**:装到当前用户的目录(`%LOCALAPPDATA%\Programs\Scoreboard_Console`;受限账户会落到这一档);**不加防火墙规则**,局域网大屏要照 7.5 手工放行一次。
- **安装位置**:向导里**默认填这台机器上次装的目录**;切换上面两种装法时,目录输入框会跟着变成该模式的默认目录;**手工改过路径(或点过「浏览…」)之后再切模式也不会冲掉你填的** —— 想回到模式默认目录,把路径清空重新切一次模式。
3. 安装完成后,桌面会出现名为**「赛事积分榜」**的快捷方式(右键 →「属性」→ 看「目标」,可确认这次装到了哪个目录)。
4. 双击「赛事积分榜」启动。
> 赛事数据、配置与规则都存放在 `%LOCALAPPDATA%\ScoreboardConsole\`(不随安装目录走,见 3.4、3.5);服务端日志在数据目录的 `data\logs\` 下,Console 自己的 `console.log` 在安装目录的 `logs\` 下(见第 10 节);安装目录本身只要当前用户可写即可。
> 赛事数据、配置与规则都存放在 `%LOCALAPPDATA%\ScoreboardConsole\`(不随安装目录走,见 3.4、3.5);服务端日志在数据目录的 `data\logs\` 下,Console 自己的 `console.log` 在**安装目录**的 `logs\` 下(见第 10 节),所以**安装目录要当前账户写得进去**。⚠️ 新版安装器默认装到 `C:\Program Files\Scoreboard_Console`;如果装完发现「运行日志」面板一直是空的、安装目录下没有 `logs\console.log`(多半就是写不进去),**改装到一个当前账户可写的普通目录**(例如 `D:\Scoreboard`)重装一次即可。
### 3.2 使用免安装包
@@ -101,7 +104,7 @@ deploy\build.bat
### 3.4 数据放在哪里(升级/卸载都不会删)
覆盖安装时安装程序会**先静默运行旧版卸载器**,而卸载器会把整个安装目录删掉,所以数据库、规则、用户、上传的图片与字体都不能放在安装目录里。现在的规则:
覆盖安装时安装程序会**先静默运行旧版卸载器**,而卸载器会把整个安装目录删掉,所以数据库、规则、用户、上传的图片与字体都不能放在安装目录里。**例外**:用 `安装包.exe /S` 做的**静默安装会跳过旧卸载器**(旧卸载器在无人值守的会话里可能弹一个没人能点的提权框)—— 但这只影响静默安装那一条路,手工卸载与交互式升级照样会删安装目录,所以数据仍然必须放在安装目录之外。现在的规则:
| 场景 | 数据目录 |
| --- | --- |
@@ -405,8 +408,10 @@ scoreboard.exe passwd -config "%LOCALAPPDATA%\ScoreboardConsole\config.yaml" -da
**防火墙要放行入站 19540**(默认端口,改过端口就换成实际端口)。安装包会替你放行,分两种情况:
- 安装时选了**「为所有用户安装」**:安装程序会弹 UAC 提权,**提权那一趟就顺手把入站 19540 放行了**(规则名 `Scoreboard Console (TCP 19540)`),装完不用再管;卸载时会自动把这条规则删掉。
- 安装时选了**「仅为我安装」**:全程不申请提权,装不了防火墙规则,**必须手工放行**。也可以重新跑一次安装程序、这次选「为所有用户安装」,让它自动放行。
- 安装时选了**「为所有用户安装」**:**提权那一趟就顺手把入站 19540 放行了**(规则名 `Scoreboard Console (TCP 19540)`),装完不用再管;卸载时会自动把这条规则删掉。
- 安装时选了**「仅为我安装」**:这一趟**不加防火墙规则**(装到用户目录,安装程序只在「为所有用户安装」那一档才去改防火墙),**必须手工放行**。也可以重新跑一次安装程序、这次选「为所有用户安装」,让它自动放行。
> ⚠️ **新版安装器一启动就会申请管理员**(`RequestExecutionLevel highest`,见 3.1):**管理员账户**的机器上,双击安装包先弹一次 UAC,**无论最后选哪种装法都会弹这一次** —— 选「为所有用户安装」才顺手放行防火墙、装到 `C:\Program Files\…`;选「仅为我安装」只装到用户目录、不加规则。**受限账户**的机器不弹 UAC,会自动落到「仅为我安装」那一档,所以这种机器一定要手工放行。
手工兜底(给「仅为我安装」的机器,以及改过端口、装了才发现要放行的机器)——在**管理员** cmd 里跑:
@@ -453,7 +458,7 @@ http://<主机IP>:19540/display
- 这个地址不用手敲:管理端「大屏控制 → 局域网大屏」卡片里有**可复制的完整链接**与**二维码**(第一个地址),别的设备扫码或在浏览器里粘贴即可打开(该卡片需录入员及以上登录才看得到);
- 需要主机设置固定 IP,且设备与主机在同一局域网;
- **主机防火墙要放行入站 19540**(默认端口):装的时候选**「为所有用户安装」**,安装程序提权时会自动放行,不用再管;选了「仅为我安装」就得手工放行一次,命令与说明见 7.5;
- **主机防火墙要放行入站 19540**(默认端口):**「为所有用户安装」会自动放行**(那一档提权时装好规则),不用再管;**「仅为我安装」不加规则、必须手工放行一次**(命令与说明见 7.5)。装的时候选哪一档,取决于 3.1 里那几行 —— 新版安装器一启动就申请管理员,但只有「为所有用户」那一趟才顺手改防火墙;
- 安卓电视一般常亮,无需额外防熄屏;
- 浏览器方案**不受** Console 的 kiosk、防熄屏、选屏控制,字体与动画表现以实际设备为准;
- 现场以 Console + HDMI 为主方案,浏览器访问作为备用。