feat: 字体可配并随赛事包打包 + 大屏调试标识收敛 + 报名表 CSV 编码兼容
三块改动,均为现场反馈:
一、字体配置与随包打包(此前「没有入口可以配置字体」,导出包也不带字体)
- 服务端新增 httpapi/fonts.go 与 4 条路由:GET /api/fonts(recorder)、
POST /api/fonts(admin,multipart file)、DELETE /api/fonts/{name}(admin)、
GET /uploads/fonts/{name}(匿名——大屏 @font-face 不带会话)
- 上传限 ttf/otf/woff/woff2、单个 20 MiB;文件名经 safeFontName 收敛且需与
fontContentType 往返一致,挡住路径穿越;重名 409、删除被引用字体 409
- 新增设置键 display.font_title / display.font_body(DTO fontTitle/fontBody,
随快照下发给大屏),写入时校验取值合法
- 导出:接上一直没被赋值的 IncludeFonts/FontsDir;包内落点用 uploads/fonts/
(运行时只读这里,落顶层 fonts/ 等于没人读)
- 大屏按配置动态注册字体并挂 --display-font-title/body,加载失败静默回落默认字体
- 管理端「赛事信息」新增字体区块:标题/正文字体下拉、上传、字体库、实时预览
二、大屏显示收敛
- 数据版本号角标 vN 彻底移除(原先只有窗口化窗口会显示,两处显隐口径不一致)
- 窗口化窗口按 F11 全屏后自绘标题栏不让位:根因是 Console 用 win.setFullScreen()
做窗口级全屏,而页面用 document.fullscreenElement 判断,后者恒为 null;
新增 display-preload.js 下发窗口级全屏状态,页面侧 shell.ts 把两级全屏取或,
无 preload 时(浏览器直连 /display)回落到文档级监听
三、报名表 CSV 编码兼容(用户报「解析中文字符遇到编码问题」)
- 服务端不再把原始字节直接喂给 csv.Reader:先摘 UTF-8 BOM,再认 UTF-16 LE/BE
BOM,其余非合法 UTF-8 按 GB18030 解(GBK 是其子集)
- 修复前症状:GBK 文件(Excel 另存为 CSV 的默认编码)中文变乱码;带 BOM 的文件
(Excel「CSV UTF-8」,也正是我们自己模板的格式)把 BOM 拼进第一列表头,
报「报名表缺少列 event_code」——连「下载模板→填→传回来」都走不通
- golang.org/x/text 由 indirect 提升为直接依赖,未新增外部依赖
测试:服务端 12 包全绿(新增 fonts_test.go / fonts_internal_test.go /
handlers_import_encoding_test.go);前端 vue-tsc 通过、pnpm build 通过、157 例全过;
Console 语法检查 17 个文件通过。docs/ 与 devdocs/ 同步更新。
This commit is contained in:
1 parent
9c6d0bd3b3
commit
fc96d17660
42 files changed
+2451
-95
No files matched your search
+16
-13
@@ -93,7 +93,7 @@ deploy\build.bat
|
||||
|
||||
### 3.4 数据放在哪里(升级/卸载都不会删)
|
||||
|
||||
覆盖安装时安装程序会**先静默运行旧版卸载器**,而卸载器会把整个安装目录删掉,所以数据库、规则、用户、上传的图片都不能放在安装目录里。现在的规则:
|
||||
覆盖安装时安装程序会**先静默运行旧版卸载器**,而卸载器会把整个安装目录删掉,所以数据库、规则、用户、上传的图片与字体都不能放在安装目录里。现在的规则:
|
||||
|
||||
| 场景 | 数据目录 |
|
||||
| --- | --- |
|
||||
@@ -102,6 +102,7 @@ deploy\build.bat
|
||||
| 直接双击 `scoreboard.exe`(不经 Console) | 服务端默认行为不变:用工作目录下的 `data\`,**这种用法在覆盖安装时仍会丢数据** |
|
||||
|
||||
- Console 启动时会把这个目录用 `-data` 参数交给服务端,界面上方「运行日志」里能看到 `数据目录:...` 这一行;
|
||||
- **上传资源随赛事项目走**:赛事会标、大屏背景图、单位 logo,以及「赛事信息 → 字体」里上传的**字体文件**,都在 `<数据目录>\event_projs\<项目名>\uploads\` 里(字体在 `uploads\fonts\`)。它们是文件而不是数据库记录,**不在 `backups\` 的 `.db` 快照里**,备份 / 迁移时要连这个目录一起拷(见 8.5、8.6);
|
||||
- **一次性迁移**:如果新数据目录还是空的,而旧的 `<安装目录>\data` 里有数据,Console 会在启动时把旧目录**整体改名**过去(同盘很快),日志里会写「已把旧数据从 X 迁移到 Y」。任何失败(跨盘、权限不足等)都只记日志,旧数据原地保留,不会被删;
|
||||
- 如果两个目录里**都有数据**,Console 不做任何动作,只写一条警告日志,由现场人工决定保留哪一份;
|
||||
- 迁移只在安装包版本(打包后)执行一次,`pnpm start` 之类的开发运行不会碰仓库里的 `data\`;
|
||||
@@ -129,7 +130,8 @@ deploy\build.bat
|
||||
- 规则目录只在首次复制一次,之后你往里面放的规则包不会被模板顶掉;
|
||||
- 某一处建不出来或不可写(权限、杀毒软件拦截等)时**只记日志并回落到安装目录里那份**,绝不因此启动失败;代价是那份改动仍会在覆盖安装时丢失,日志里会明确写出来;
|
||||
- 开发运行(`pnpm start`)不接管这三项,仍用仓库里的 `console\config.json`、`config.yaml`、`rules\`;
|
||||
- 不用 Console、直接双击 `scoreboard.exe` 时,服务端仍按工作目录下的 `config.yaml` 读配置,**不受这套保护**。
|
||||
- 不用 Console、直接双击 `scoreboard.exe` 时,服务端仍按工作目录下的 `config.yaml` 读配置,**不受这套保护**;
|
||||
- 上传的图片与字体不在这三项里,位置见 3.4:它们随赛事项目存放在数据目录的 `event_projs\<项目名>\uploads\`(字体在 `uploads\fonts\`),同样在安装目录之外,覆盖安装不会动它们;**但它们不在 `backups\` 的数据库快照里**,备份 / 迁移时要连这个目录一起拷(见 8.6)。
|
||||
|
||||
> 从老版本覆盖升级上来的第一次启动:安装目录里那三份在覆盖安装时**就已经被旧卸载器删过一遍**(新装进去的是新版模板),Console 只能把模板复制到用户目录,升级前改在安装目录里的配置需要重做一遍。**从本版本起**(也就是改动落在上表位置之后),配置与规则才会跨升级保留。
|
||||
|
||||
@@ -328,15 +330,15 @@ scoreboard.exe passwd -config "%LOCALAPPDATA%\ScoreboardConsole\config.yaml" -da
|
||||
### 7.3 单屏:窗口化 + F11
|
||||
|
||||
- 只有一块屏时,大屏以窗口化方式打开(屏幕 80% 大小、居中),并显示自绘标题栏;
|
||||
- 在窗口内按 **F11** 切换全屏 / 窗口;
|
||||
- 在窗口内按 **F11** 切换全屏 / 窗口:全屏时自绘标题栏与「实例 · 屏」标识一起隐藏、画面铺满整块屏;再按一次恢复;
|
||||
- 单屏模式不跟随显示器变化重排;
|
||||
- 窗口化时右上角会显示「实例 … · 屏 …」与数据版本号(`v<n>`)供现场核对;按 F11 全屏后「实例 · 屏」自动隐藏,版本号角标仍在(它只跟「这个窗口是不是窗口化打开的」有关,见 7.7)。
|
||||
- 窗口化且未全屏时右上角显示一行「实例 … · 屏 …」供现场核对(数据版本号角标已移除,见 7.7)。
|
||||
|
||||
### 7.4 多屏:每屏锁一页
|
||||
|
||||
- 除内置屏外的每块屏各开一个 kiosk 全屏窗口;
|
||||
- 每块屏**锁定一个页面**,按 `display.pages` 的顺序轮转分配;
|
||||
- 多屏 kiosk 不响应 F11,也不接收鼠标(`ignoreMouse`),也不显示任何调试标识与版本号角标;
|
||||
- 多屏 kiosk 不响应 F11,也不接收鼠标(`ignoreMouse`),也不显示任何调试标识;
|
||||
- 可用的页面值:`standings`(总积分榜)、`medals`(团体奖牌榜)、`individual`(个人积分奖牌榜)、`results`(分项成绩)、`announcement`(公告);管理端切页用的是同一批页面的规范名 `team-medals` / `athlete-standings` / `event-results`,两种写法大屏都认。
|
||||
|
||||
### 7.5 在管理端单独控制某块屏
|
||||
@@ -360,7 +362,7 @@ scoreboard.exe passwd -config "%LOCALAPPDATA%\ScoreboardConsole\config.yaml" -da
|
||||
|
||||
### 7.7 大屏画面里的调试标识与单位 logo
|
||||
|
||||
- **调试标识**:只有窗口化打开的大屏窗口才会显示「实例 … · 屏 …」与数据版本号 `v<n>`(`v<n>` 是数据版本号,与管理面板顶部的版本号一致就说明这块屏已跟上服务端);**多屏 kiosk 全屏完全不带这些标识**,窗口化窗口按 F11 全屏后「实例 · 屏」也会隐藏、版本号角标仍在。要一个完全干净的展示画面,就用多屏 kiosk;
|
||||
- **调试标识**:只有**窗口化且没有全屏**的大屏窗口才会显示一行「实例 … · 屏 …」;**多屏 kiosk 全屏完全不带调试标识**,单屏窗口化窗口按 F11 全屏后它也会连同自绘标题栏一起隐藏。数据版本号角标 `v<n>` 已移除,任何情况下都不再显示(要核对某块屏是否跟上服务端,看管理端仪表盘「实时连接」里的「版本 N」)。要一个完全干净的展示画面,就用多屏 kiosk;
|
||||
- **单位 logo**:参赛单位的 logo 会显示在总积分榜、团体奖牌榜、分项成绩表与个人积分榜上(个人榜显示在姓名前);没上传 logo 的单位不占位。logo 在「基础数据 → 参赛单位」里上传,随赛事项目包一起导出/导入(见 8.5)。
|
||||
|
||||
### 7.8 大屏窗口的自动行为
|
||||
@@ -452,7 +454,7 @@ http://<主机IP>:19540/display
|
||||
|
||||
- `meta.yaml`:包格式标识、项目名、赛事名称/副标题/主办方、导出时间,以及每个文件的 SHA-256 清单(导入时逐个校验,对不上就拒绝);
|
||||
- `event.db`:赛事库快照(用 `VACUUM INTO` 生成,导出时服务端可以继续写入),成绩、基础数据、积分规则都在里面;
|
||||
- `uploads/`:**全部上传图片**——赛事会标、大屏会标、大屏背景图、各参赛单位 logo 等(在「系统设置 → 赛事信息」与「基础数据 → 参赛单位」里上传的那批文件)。导入时会连图片一起落到新项目目录,切换过去后直接显示,不用重新上传;
|
||||
- `uploads/`:**全部上传资源**——赛事会标、大屏会标、大屏背景图、各参赛单位 logo,以及**上传的字体**(放在 `uploads/fonts/` 下,见使用手册 14.3)。导入时会连文件一起落到新项目目录的 `uploads/`,切换过去后图片直接显示、字体直接可用,不用重新上传;
|
||||
- `rules.yaml`:当前规则包的一份 YAML 副本,便于单独复用到别的赛事;规则本身存在赛事库里,导入后即刻生效,这份只是副本。
|
||||
|
||||
导出界面同一页的「结果导出」标签可以把最终结果导成 xlsx:**总表**(总积分榜 + 团体奖牌榜 + 个人积分奖牌榜,一个工作簿)、**全部**(总表 + 全部分项)、**分项成绩表**(按小项)、**单位积分明细**(按单位)四项各自可单独导出打印。
|
||||
@@ -466,21 +468,21 @@ http://<主机IP>:19540/display
|
||||
|
||||
- 不能覆盖**正在运行**的赛事项目:对当前赛事的同名包,导入会被直接拒绝(先切到别的赛事再导);
|
||||
- 勾选「覆盖同名项目」时,旧目录会先改名保留、新项目落盘成功后才删除它;
|
||||
- 参赛单位 logo、会标、背景图都在 `uploads\` 里,所以**备份 / 迁移时要连 `event_projs\<项目名>\uploads\` 一起拷**(见 8.6);
|
||||
- 参赛单位 logo、会标、背景图与上传的字体都在 `uploads\` 里,所以**备份 / 迁移时要连 `event_projs\<项目名>\uploads\` 一起拷**(见 8.6);
|
||||
- **不要用 `-project` 启动参数来切赛事**:显式传 `-project` 时,服务端会顺手把它写回「上次打开的赛事」记忆文件,于是以后每次启动都优先打开这个项目——在页面里切完、重启后又被拉回去。只有在「刻意把一台机器固定成只开某一个项目」时才这么用:在 Console 的用户配置 `config.json` 里给 `server.args` 加 `"-project","<项目名>"` 后重启 Console,或直接 `scoreboard.exe -config "%LOCALAPPDATA%\ScoreboardConsole\config.yaml" -project <项目名> -data "%LOCALAPPDATA%\ScoreboardConsole\data"` 启动(见 6.2)。
|
||||
|
||||
### 8.6 手工备份 / 迁移整个数据目录
|
||||
|
||||
快照备份之外,数据库文件、上传的图片、备份都可以整体拷走:
|
||||
快照备份之外,数据库文件、上传的图片与字体、备份都可以整体拷走:
|
||||
|
||||
1. 在 Console 里**停止服务**(托盘 → 停止服务),避免拷贝过程中继续写入;
|
||||
2. 把整个数据目录 `%LOCALAPPDATA%\ScoreboardConsole\data` 复制到 U 盘或其他盘(里面含 `system.db`、`event_projs\`(数据库 + `uploads\` 图片)、`backups\`);
|
||||
2. 把整个数据目录 `%LOCALAPPDATA%\ScoreboardConsole\data` 复制到 U 盘或其他盘(里面含 `system.db`、`event_projs\`(数据库 + `uploads\` 图片与字体)、`backups\`);
|
||||
3. 恢复时把整个目录拷回去,然后:
|
||||
- 拷回**原路径**:直接启动 Console 即可;
|
||||
- 拷到**别的路径**:先建好目标目录并放入数据,再在用户配置 `console\config.json` 里把 `server.dataDir` 指向它,重启 Console;
|
||||
4. 恢复完成后在管理端核对赛事、账号、上传图片是否齐全。
|
||||
4. 恢复完成后在管理端核对赛事、账号、上传图片与字体是否齐全。
|
||||
|
||||
> 只拷 `backups\` 里的 `.db` 快照也能救回成绩数据,但上传的背景图/会标在 `event_projs\<项目名>\uploads\` 里,不拷这个目录会丢图片。
|
||||
> 只拷 `backups\` 里的 `.db` 快照也能救回成绩数据,但上传的背景图/会标/单位 logo **与自定义字体**在 `event_projs\<项目名>\uploads\` 里(字体在 `uploads\fonts\`),不拷这个目录会丢这些文件,大屏上表现为图片不显示、字体回落成默认字体。
|
||||
|
||||
---
|
||||
|
||||
@@ -581,11 +583,12 @@ http://<主机IP>:19540/display
|
||||
- [ ] 「运行日志」里的 `数据目录:` 指向 `%LOCALAPPDATA%\ScoreboardConsole\data`(不是安装目录),且没有迁移警告
|
||||
- [ ] 「运行日志」里的 `用户数据目录:` 指向 `%LOCALAPPDATA%\ScoreboardConsole`,且没有「准备 … 失败」警告(配置与规则也在用户目录里,见 3.5)
|
||||
- [ ] 数据目录的 `backups\` 可写,已生成至少一份备份
|
||||
- [ ] 已把数据目录整个拷一份到 U 盘(含 `event_projs\<项目名>\uploads\` 里的图片)
|
||||
- [ ] 已把数据目录整个拷一份到 U 盘(含 `event_projs\<项目名>\uploads\` 里的图片与字体)
|
||||
- [ ] **当前赛事正确**:「导出 → 赛事项目包 → 赛事项目列表」里带「当前」徽标的是本次要用的那个项目(刚导入的包要切换过去才算生效,见 8.5)
|
||||
- [ ] 大屏 HDMI 输出定位正确、分辨率正确、字体正常
|
||||
- [ ] **显示器菜单可用**:在服务管理窗口打开的「大屏控制」页里能看到每块屏并「创建全屏窗口」,副屏被误关时能重开(见 7.5)
|
||||
- [ ] **单位 logo 已上传且在榜上显示**(总积分榜 / 团体奖牌榜 / 分项成绩表 / 个人积分榜,见 7.7)
|
||||
- [ ] **大屏字体已选好并核对**:「系统设置 → 赛事信息 → 字体」里选了标题字体与正文字体,大屏上显示正常;上传的字体在数据目录 `event_projs\<项目名>\uploads\fonts\` 里,导出赛事项目包会一并带走(见 8.5)
|
||||
- [ ] **公告可用**:推送一条测试公告,全屏到时后底栏仍能看到正文,点「清除公告」后底栏回到「暂无公告」(见 7.6)
|
||||
- [ ] 管理端各角色账号可登录,权限正确
|
||||
- [ ] 主机 IP 固定,管理端 / 大屏地址已打印或做成二维码贴在操作台
|
||||
|
||||
Reference in new issue
Block a user