Files
Scoreboard/docs/上线检查清单.md
T
AskaEth e5e0944d26 feat: 分级拦截日志 + 两类日志文件;成绩录入防呆/解析/宽度修复
## 日志(用户要求:分级 + 每个拦截都要有指出代码行的调试日志 + 两类文件)
- 新增 internal/logging:拦截点捕获(file:line + 函数名,相对路径)、两类文件轮转、
  按级别/类别分流。httpapi 与 middleware 各自薄封装,无循环依赖。
- 两类目录(数据目录下):
  operations/     放行类(INFO「操作已放行」+ 常规运行日志,按 log.level)
  interceptions/  拦截类(WARN 中文原因 + 拦截点 + method/path/actor/role/requestId、
                  DEBUG 上下文、ERROR 服务端异常)—— **固定 debug 采集**,
                  否则默认 info 下"每次拦截的调试日志"根本看不见
- 命名 operations-YYYYMMDD[.N].log,按天+按大小轮转,每类保留 keepFiles 份;写盘失败
  降级只写控制台且只 Warn 一次。
- 所有业务错误统一走 newAPIError 捕获拦截点(11 处内联 &apiError{} 已收进构造函数,
  防止绕过);中间件层拦截(401/403/CSRF/未改初始密码/429)也留痕,响应体与状态码一字未变。
- config.yaml 的 log 段新增 dir / maxSizeMB / keepFiles(留空即默认)。
- 服务端包数 12 → 13(新增 internal/logging)。

## 成绩录入(用户实机踩坑)
- 真因一:成绩格 placeholder 是光秃秃的 `1:06.33`,而全仓库没有任何 ::placeholder 样式,
  示例文本与真实输入长得一样 → 用户把灰字当成已填内容,那 13 格其实是空的。
- 真因二:2 条报错是秒位 ≥ 60(1:70)或全角冒号(1:06);1:06 与 1:06.00 在解析器里
  本来就等价(都 = 66),格式不是问题。
- 真因三:成绩格没有宽度定义(旁边名次 72px、状态 110px 都有),被挤到第 4 位数字看不见。

修复:parseSecondsDetail 区分 empty/seconds-overflow/unrecognized;新增 entryGuards.ts
纯函数(录入页与审核页共用),报错**打出那一格的实际内容**并说明原因;解析器新认全角
冒号/全角数字/1分06秒 等写法;成绩格 min-width 112px(按 fontTools 实测文本宽度定);
示例文本改 `例 1:06.33` 等并给录入表格内的 ::placeholder 加淡色斜体;新增
onBeforeRouteLeave 离开守卫(原来切菜单会静默丢未保存成绩)。

测试:服务端 13 包全绿(372 个测试函数);前端 vue-tsc 通过、205 例全过;Console 18 文件。
docs/ 与 devdocs/ 同步(FAQ 到 Q76,部署指南新增第 10 节「服务端日志与拦截复盘」)。
2026-09-11 01:59:58 +08:00

85 lines
8.7 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.
# 上线检查清单
> 比赛当天照着走一遍即可。细节见 [部署指南](./部署指南.md) 与 [使用手册](./使用手册.md)。
## 1. 交付物
| 文件 | 用途 |
| --- | --- |
| `Scoreboard Console-0.1.0-x64.exe` | NSIS 安装包(推荐),双击按向导装 |
| `Scoreboard Console-0.1.0-x64.zip` | 免安装包,解压即用 |
| `scoreboard.exe` | 服务端本体(已内嵌前端页面) |
> 校验完整性:`certutil -hashfile "Scoreboard Console-0.1.0-x64.exe" SHA256`
## 2. 目标机(服务端主机)
- [ ] Windows 10/11 x64,接市电(建议接 UPS)
- [ ] 端口 **19540** 未被占用:`netstat -ano | findstr 19540`
- [ ] 数据/配置目录可写:默认 `%LOCALAPPDATA%\ScoreboardConsole\`(数据在 `data\`,配置与规则是 `console\config.json`、`config.yaml`、`rules\`;都在安装目录之外,升级/卸载都不会删),需要放行杀毒/防火墙
- [ ] 大屏通过 HDMI 接在**同一台机器**上(系统显示模式设为「扩展」)
- [ ] 显示器数量确认:只接一块屏时大屏只能窗口化(按 F11 可切全屏);要每屏一个 kiosk 全屏窗口就得接第二块屏(见部署指南 7.3、7.5)
- [ ] **安装目录不要选 `C:\Program Files`**(那里普通用户没写权限,日志会写不进去);装到 D 盘等普通目录即可,向导里可以改路径
## 3. 首次启动
- [ ] 双击 `Scoreboard_Console.exe`,启动管理窗口出现
- [ ] 服务端状态变为「运行中 · 就绪」
- [ ] 「运行日志」里 `数据目录:` 指向 `%LOCALAPPDATA%\ScoreboardConsole\data`(**不是**安装目录),且没有「都有数据 / 迁移失败」的警告
- [ ] 「运行日志」里 `用户数据目录:` 指向 `%LOCALAPPDATA%\ScoreboardConsole`,且没有「准备 … 失败」的警告(配置与规则也在那儿,见部署指南 3.5)
- [ ] 打开管理面板(窗口内「打开服务端管理面板」按钮),用管理员账号登录
- [ ] **管理员初始密码**在 `logs\console.log` 里搜 `INITIAL ADMIN CREATED`,密码就在该行上方;也可以直接打开 Console 的「运行日志」面板往上翻。首次登录会要求改密
## 4. 赛事配置(管理员)
- [ ] 「系统设置 → 赛事信息」的**基本信息**:填名称、副标题、主办方,上传**赛事会标**
- [ ] 同页的**大屏配置**:上传大屏会标、选大屏背景图,填大屏标题 / 副标题、轮播间隔与主题色(上传的图片随赛事项目包一起导出/导入)
- [ ] 同页的**字体**:确认**标题字体**与**正文字体**已选好(默认、四款内置字体,或自己上传的字体);选完点「保存」,并核对大屏上标题与正文显示正常。上传的字体存在赛事项目的 `uploads\fonts\` 里,**导出赛事项目包会一并带走、导入后不用重新上传**(见使用手册 14.3、部署指南 8.5)
- [ ] **赛事项目确认 / 导入**:到「导出 → 赛事项目包」核对**赛事项目列表**里带「当前」徽标的是本次要用的赛事;需要换赛事时先「导入 .zip」,再点「切换为当前赛事」(服务端会重启一次,页面显示「正在重启服务端…」,恢复后自动刷新)。账号与会话在数据目录的 `system.db` 里,**不受切换影响**,一般不用重新登录。这一步做完再往下走,否则后面看到的是别的赛事的数据
- [ ] **导入规则包**:`%LOCALAPPDATA%\ScoreboardConsole\rules\2026-驭电利刃杯军事运动会.yaml`,走「导出 → 规则包 → 选择 YAML → 预览差异 → 确认导入并全量重算」(规则目录在用户数据目录里,见部署指南 3.5)
—— 服务端不会自动加载规则包,必须导入一次
- [ ] 检查计分模板:个人前六名 `10/8/6/3/2/1`、团体 `15/10/8/4/2/1`、最后一名不得分
- [ ] 「只排名不计分」的项目(飞行人员战斗体能)导入后应显示为不计分
- [ ] 「基础数据 → 参赛单位」里各单位的 logo 都已上传(会显示在总积分榜、团体奖牌榜、分项成绩表与个人积分榜上)
- [ ] 同页核对**单位名单齐全、没有误删**:被「彻底删除」的单位不会出现在这个列表里(它的报名、成绩与积分仍在库里,积分榜照常显示它);发现少了就用它的编码导入一次报名表,它会重新出现(详见使用手册 10.1、常见问题 Q61–Q64)
## 5. 大屏
- [ ] 接好扩展屏后,服务管理窗口点「重新排布」
- [ ] 确认大屏锁定在「积分榜」页面;需要轮播就在后台开启
- [ ] 鼠标移到大屏上应看不到操作按钮;大屏窗口已开防熄屏
- [ ] 只有一块屏时是窗口化模式,按 **F11** 可切全屏(用于单屏测试)
- [ ] **调试标识已隐藏**:多屏 kiosk 全屏画面上不该出现「实例 … · 屏 …」;窗口化窗口(单屏)里显示这一行属正常,按 F11 全屏后它与自绘标题栏一起消失(版本号角标已移除,任何画面都不该出现)
- [ ] **显示器菜单可用**:在服务管理窗口里点「打开服务端管理面板」,进「大屏控制 → 显示器」,能看到每块屏;副屏点「创建全屏窗口」能重新开出来(单屏 / 主显示器只能窗口化,属正常)
- [ ] **在线大屏与逐屏切页**:同页右侧「在线大屏」列表能看到本机每块屏的在线实例(局域网设备也已在这一列表里,标记为「局域网浏览器」),每行显示当前所在页;用某一行自己的下拉 +「切到此页」能把那一块屏 / 那台设备单独切走,其余屏不受影响(离线实例的控件为灰色,属正常)
- [ ] **公告可用**:推送一条测试公告 → 大屏全屏显示 → 到时退回原页且**底栏公告栏仍常驻显示正文** → 点「清除公告」后底栏回到「暂无公告」
## 6. 数据与备份
- [ ] 确认数据目录 `%LOCALAPPDATA%\ScoreboardConsole\data` 下的 `backups\` 里已出现 `system-auto-*.db` 与 `event-auto-*.db`(默认每 5 分钟)
- [ ] 确认数据目录下已生成 `logs\operations\` 与 `logs\interceptions\`(服务端日志,见部署指南第 10 节),并知道操作被拒时去 `interceptions\` 当天文件里搜原因与拦截点
- [ ] 开幕前手动点一次「立即备份」(「系统设置 → 备份 → 立即备份」)
- [ ] 把整个数据目录(不只是 `backups\`:`event_projs\<当前项目名>\uploads\` 里还有会标、背景图、单位 logo 与上传的字体)拷一份到 U 盘
- [ ] 留一份成绩总表存档:到「导出 → 结果导出」导一份**全部(单页)**(`赛事成绩总表(单页).xlsx`,一个工作簿一张表,适合比对与筛选),需要归档打印再导一份「全部」(多 sheet)
## 7. 现场流程演练(建议至少一次)
- [ ] 录入员登录 → 录入一条成绩 → 存草稿 → 发布 → 大屏刷新
- [ ] 撤销发布 → 修改 → 重新发布(历史记录里能看到链路)
- [ ] 导出核对:「结果导出」里「全部」与「全部(单页)」都能正常下载(后者应是一个工作簿、只有一张表);「积分榜」页三个榜单的卡片头各有导出——单位总分榜「导出总明细」得到 `单位积分总明细.xlsx`、团体奖牌榜「导出奖牌明细」得到 `团体奖牌明细.xlsx`、个人积分榜「导出个人明细」得到 `个人积分总明细.xlsx`;展开某单位后还能点「导出该单位明细」得到 `单位积分明细.xlsx`
- [ ] 断网 → 大屏仍显示缓存数据 → 恢复后自动补增量
- [ ] 重启服务端 → Console 自动拉起
## 8. 出问题时的回退
| 故障 | 动作 |
| --- | --- |
| 服务端无响应 | 服务管理窗口「重启服务」 |
| 导入赛事包后看不到数据 | 到「导出 → 赛事项目包 → 赛事项目列表」把该项目「切换为当前赛事」(服务端会重启一次,页面恢复后自动刷新,一般不用重新登录),详见部署指南第 8.5 节 |
| 主机死机 | 备机启动同一份部署包,把用户数据目录(`%LOCALAPPDATA%\ScoreboardConsole\`,含数据、配置与规则)拷回去 |
| 数据库损坏 | 停机,用数据目录下 `backups\` 的最新备份替换 `event_projs\<项目名>\event.db`(先删 `-wal`/`-shm`),详见部署指南第 8.3 节 |
| 大屏黑屏 / 窗口被误关 | 服务管理窗口「重新排布」;仍不行就到「大屏控制 → 显示器」点该块屏的「创建全屏窗口」;最后才用备用笔记本开同一地址 |
| 覆盖安装后数据/配置不见了 | 看「运行日志」里的 `数据目录:`、`用户数据目录:` 与迁移警告,按部署指南第 9.9 节处理 |
> 完整恢复步骤见 [部署指南 · 备份与恢复](./部署指南.md#8-备份与恢复)。