feat: 大屏控制可看局域网设备并逐台切页 + 两种新导出(单页成绩 / 单位积分总明细)
## 大屏控制(用户:管理面板只能看到本机显示器,看不到局域网设备;也不能给某块屏单独切页) - 服务端:`POST /api/display/command` 新增可选 `targets []string` —— 空 = 广播(公告语义不变), 非空 = 只发给点名的实例并返回命中数;命中 0 个返回 404 +「目标大屏已离线,请刷新在线列表」 (不落审计、公告也不落库)。`DisplaySender` 签名随之扩展,新增 `Hub.SendCommandToInstances`(与按房间的 SendCommand 并存)。 - 服务端:WS `hello` 新增可选 `screen`,`realtime.Instance` 新增 `Screen`(不带 omitempty, 局域网浏览器恒为空串),这样管理端能把「本机显示器」与「在线实例」精确对上。 - 管理端「大屏控制」:写死的「在线看板」占位换成真实列表(5 秒轮询、页面隐藏停表), 列出实例 id / 在线离线 / 落后 / 屏号或「局域网浏览器」/ 当前页 / 来源 / 心跳; 每行可单独切页;本机显示器卡片补「当前页」与逐屏切页;离线时控件置灰并说明原因。 页面下拉改为共用大屏那份页名清单(管理端两处标签随之变为「个人积分奖牌榜」「分项成绩」)。 ## 导出(用户:保留多页工作簿的同时,再要一种全平铺单页;积分榜明细也要能导出) - 新增 `GET /api/export/all-flat.xlsx` → `赛事成绩总表(单页).xlsx`:一个工作簿一张表, 列 = 大项/小项/组别/名次/号码/单位/运动员-队/成绩/积分/状态/备注;前三列取 `EventSheet` 的结构化字段(不解析标题),后 8 列就是 `eventColumns` 本身(append 拼出, 两处不可能漂移)。**既有「全部」(all.xlsx,多 sheet)一字未动。** - 新增 `GET /api/export/teams.xlsx` → `单位积分总明细.xlsx`:一张带「单位」列的总表 + 每个有明细行的单位一张分表;**无明细行的单位不出分表**(空表没信息量,且会把假删除的 隐藏单位名字重新印进导出件);已隐藏但有流水的单位照常出表(它在榜单上)。 - 积分榜页:页头「导出总明细」、单位明细面板「导出该单位明细」;导出页新增「全部(单页)」。 测试:服务端 12 包全绿 / 347 个测试函数;前端 vue-tsc 通过、184 例全过;Console 18 文件。 docs/ 与 devdocs/ 同步(含新增 Q65–Q70 与两轮进度记录)。
This commit is contained in:
1 parent
793d2ac064
commit
782a38f82f
33 files changed
+2473
-119
No files matched your search
@@ -51,6 +51,7 @@
|
||||
- [ ] 只有一块屏时是窗口化模式,按 **F11** 可切全屏(用于单屏测试)
|
||||
- [ ] **调试标识已隐藏**:多屏 kiosk 全屏画面上不该出现「实例 … · 屏 …」;窗口化窗口(单屏)里显示这一行属正常,按 F11 全屏后它与自绘标题栏一起消失(版本号角标已移除,任何画面都不该出现)
|
||||
- [ ] **显示器菜单可用**:在服务管理窗口里点「打开服务端管理面板」,进「大屏控制 → 显示器」,能看到每块屏;副屏点「创建全屏窗口」能重新开出来(单屏 / 主显示器只能窗口化,属正常)
|
||||
- [ ] **在线大屏与逐屏切页**:同页右侧「在线大屏」列表能看到本机每块屏的在线实例(局域网设备也已在这一列表里,标记为「局域网浏览器」),每行显示当前所在页;用某一行自己的下拉 +「切到此页」能把那一块屏 / 那台设备单独切走,其余屏不受影响(离线实例的控件为灰色,属正常)
|
||||
- [ ] **公告可用**:推送一条测试公告 → 大屏全屏显示 → 到时退回原页且**底栏公告栏仍常驻显示正文** → 点「清除公告」后底栏回到「暂无公告」
|
||||
|
||||
## 6. 数据与备份
|
||||
@@ -58,11 +59,13 @@
|
||||
- [ ] 确认数据目录 `%LOCALAPPDATA%\ScoreboardConsole\data` 下的 `backups\` 里已出现 `system-auto-*.db` 与 `event-auto-*.db`(默认每 5 分钟)
|
||||
- [ ] 开幕前手动点一次「立即备份」(「系统设置 → 备份 → 立即备份」)
|
||||
- [ ] 把整个数据目录(不只是 `backups\`:`event_projs\<当前项目名>\uploads\` 里还有会标、背景图、单位 logo 与上传的字体)拷一份到 U 盘
|
||||
- [ ] 留一份成绩总表存档:到「导出 → 结果导出」导一份**全部(单页)**(`赛事成绩总表(单页).xlsx`,一个工作簿一张表,适合比对与筛选),需要归档打印再导一份「全部」(多 sheet)
|
||||
|
||||
## 7. 现场流程演练(建议至少一次)
|
||||
|
||||
- [ ] 录入员登录 → 录入一条成绩 → 存草稿 → 发布 → 大屏刷新
|
||||
- [ ] 撤销发布 → 修改 → 重新发布(历史记录里能看到链路)
|
||||
- [ ] 导出核对:「结果导出」里「全部」与「全部(单页)」都能正常下载(后者应是一个工作簿、只有一张表);「积分榜」页点「导出总明细」得到 `单位积分总明细.xlsx`,展开某单位后点「导出该单位明细」得到 `单位积分明细.xlsx`
|
||||
- [ ] 断网 → 大屏仍显示缓存数据 → 恢复后自动补增量
|
||||
- [ ] 重启服务端 → Console 自动拉起
|
||||
|
||||
|
||||
+20
-5
@@ -201,9 +201,17 @@
|
||||
### 8.2 团体奖牌榜 / 个人积分榜
|
||||
|
||||
- 团体奖牌榜显示金、银、铜与合计;
|
||||
- 个人积分榜显示运动员、单位、个人总分与奖牌数。
|
||||
- 个人积分榜显示运动员、单位、个人总分与奖牌数;
|
||||
- 团体奖牌榜那一列的「明细」展开的是**同一个单位积分明细面板**(见 8.1),不是奖牌专属明细;个人积分榜**没有明细列**。
|
||||
|
||||
### 8.3 推送明细到大屏
|
||||
### 8.3 导出明细(xlsx)
|
||||
|
||||
- **导出总明细**:页头右上角的按钮,导出 `单位积分总明细.xlsx`——一张带「单位」列的总表,外加每个**有数据**的单位一张分表;没有积分的单位不出分表;
|
||||
- **导出该单位明细**:右侧单位明细面板头部的按钮,先展开某个单位再点,导出 `单位积分明细.xlsx`(列:序号、大项、小项、组别、运动员、名次、成绩、来源、积分、备注,末行是「合计」);
|
||||
- 团体奖牌榜展开的也是这个单位积分明细面板,所以同样用「导出该单位明细」导出;个人积分榜没有明细列,也就没有对应的导出;
|
||||
- 两个导出都是只读下载(访客也能用),不需要写权限;导出过程中按钮会变成「导出中…」并禁用,避免重复下载。
|
||||
|
||||
### 8.4 推送明细到大屏
|
||||
|
||||
1. 展开某个单位的明细;
|
||||
2. 点「推送到大屏」;
|
||||
@@ -216,7 +224,7 @@
|
||||
|
||||
| 区块 | 操作 |
|
||||
| --- | --- |
|
||||
| 切页 | 选择「总积分榜 / 团体奖牌榜 / 个人积分榜 / 最新成绩」,点「立即跳转」 |
|
||||
| 切页 | 选择「总积分榜 / 团体奖牌榜 / 个人积分奖牌榜 / 分项成绩 / 公告」,点「立即跳转」(**所有大屏一起切**);只想切某一块屏或某台设备,用右侧「在线大屏」卡片里那一行的下拉与「切到此页」 |
|
||||
| 锁定与刷新 | **锁定**:停止自动轮播并停在当前页;**解锁**:恢复轮播;**强制刷新**:让所有大屏重新拉取快照,用于排障 |
|
||||
| 公告 | 输入公告文字,设置「滚动时长」(5–120 秒,实际是全屏展示的秒数),点「推送公告」;点「清除公告」撤下当前公告 |
|
||||
|
||||
@@ -224,7 +232,9 @@
|
||||
|
||||
**公告**:点「推送公告」后所有大屏先**全屏**展示这条公告,到时间后自动退回原来的页面(没锁定就继续轮播),公告正文留在底栏的「公告」槽位继续显示,直到被新公告替换或点「清除公告」。公告卡片顶部徽标显示「当前公告:有 / 无」,徽标下面那一行就是当前公告正文(没有公告时显示「暂无公告(大屏底栏显示占位)」)。公告会随赛事设置保存:新开的大屏窗口、断线重连之后,会先把当前公告再全屏播一遍(默认 15 秒)后留在底栏;点「清除公告」后底栏回到「暂无公告」占位。
|
||||
|
||||
**在线看板**:本页这块在线状态是**本机占位显示**(管理端网页没有接服务端的实例接口),因此恒显示「未知」,「最近下发」只是本机下发指令的时间,**不代表大屏在线**。要看真正在线的实例,用**服务管理窗口**的「已连接的大屏实例」卡片——它读服务端的 `GET /api/display/instances`,每 5 秒刷新一次,列出在线实例数与各自页面(需先以记录员及以上身份在管理面板登录过)。
|
||||
**在线大屏**:右侧「在线大屏」卡片列出的是**真实**的在线实例,直接读服务端 `GET /api/display/instances`,打开页面时每 5 秒自动刷新一次(浏览器切到后台时暂停,切回来立刻补一次)。每个实例一行,显示实例 ID、在线 / 离线徽标、「局域网浏览器」或「屏 N」标记、当前所在页、来源地址与最后心跳;服务端判定某个实例落后时还会多一个「落后」徽标(大屏可能在卡或网络差)。**本机用 Console 打开的大屏窗口、以及局域网设备打开 `/display` 连上的浏览器,都会出现在这里**——局域网浏览器没有屏号,那一栏显示「局域网浏览器」。离线实例会在服务端保留一段时间,方便排查它是什么时候掉的。
|
||||
|
||||
**逐屏 / 逐设备切页**:在线大屏列表里每一行都在「当前页」旁带一个页面下拉和「切到此页」按钮,只把**这一块屏 / 这一台设备**切过去,其他屏不受影响;上方「切页」卡片里的「立即跳转」则是**所有大屏一起切**。离线实例的下拉与按钮是灰的,发不到它;点名的大屏一台都没收到指令时会明确提示「目标大屏已离线,请刷新在线列表」,不会谎报成功。列表读取失败时页面会提示「读取在线大屏失败」,并保留上一次的结果,不会把列表清空。
|
||||
|
||||
### 9.1 显示器菜单(重建被关掉的大屏窗口)
|
||||
|
||||
@@ -233,8 +243,9 @@
|
||||
这张「显示器」卡片只在**从服务管理窗口点「打开服务端管理面板」打开的面板**里可用;用浏览器直接打开管理面板时,卡片只显示一行提示,这是正常的。
|
||||
|
||||
1. **窗口页面**:先选好新窗口锁定显示哪一页(默认「总积分榜」);
|
||||
2. **显示器列表**:逐块屏列出名称、分辨率、缩放、是否主显示器,以及当前是否已开窗口(「已开窗口(全屏)」「已开窗口(窗口化)」或「未开窗口」);
|
||||
2. **显示器列表**:逐块屏列出名称、分辨率、缩放、是否主显示器、当前是否已开窗口(「已开窗口(全屏)」「已开窗口(窗口化)」或「未开窗口」),以及**该屏窗口当前在哪一页**(没开窗口时显示「窗口未开」;窗口开着但还没上报时显示「未上报」);
|
||||
3. **每行的按钮**:
|
||||
- 该屏的窗口已连上服务端(列表里能找到对应的在线实例)→ 页面下拉 + **切到此页**:只把这一块屏切过去,不影响别的屏;找不到对应在线实例时这两个控件是灰的,行内会注明原因(「该屏窗口已关闭(实例离线),先开窗或等它重连」或「该屏窗口未开,或大屏没上报屏号」);
|
||||
- 该屏已经有窗口 → **聚焦窗口**:把窗口提到最前,不重建、不打断正在展示的比分;
|
||||
- 该屏还没有窗口,且允许多屏全屏 → **创建全屏窗口**;
|
||||
- 该屏还没有窗口,但不允许全屏 → **创建窗口(窗口化)**,行内会注明「单显示器 / 主显示器只能窗口化」;
|
||||
@@ -446,10 +457,12 @@
|
||||
| --- | --- | --- |
|
||||
| 总表 | 总积分榜 + 团体奖牌榜 + 个人积分奖牌榜,一个工作簿 | `总积分榜.xlsx` |
|
||||
| 全部 | 总表 + 全部分项,多 sheet 工作簿,适合归档打印 | `赛事成绩总表.xlsx` |
|
||||
| 全部(单页) | 所有单位、所有项目、所有成绩**平铺在一张表**里(一个工作簿只有一张表),适合筛选与二次统计 | `赛事成绩总表(单页).xlsx` |
|
||||
| 分项成绩表 | 选择一个小项导出成绩与积分 | `分项成绩表.xlsx` |
|
||||
| 单位积分明细 | 选择一个单位,逐项列出得分来源 | `单位积分明细.xlsx` |
|
||||
|
||||
- 「分项成绩表」需先选择小项,「单位积分明细」需先选择单位;
|
||||
- **「全部」与「全部(单页)」的区别**:两者内容同源,覆盖的都是全部小项的全部报名 / 成绩;「全部」把每个小项放成一张分表(多 sheet 工作簿),「全部(单页)」把所有行平铺进同一张表,每行前面补「大项 / 小项 / 组别」三列以便脱离表名也能看懂。单页表的列是:大项、小项、组别、名次、号码、单位、运动员/队、成绩、积分、状态、备注;
|
||||
- 导出文件由浏览器直接下载,表头、合并单元格与字体已按打印模板预设。
|
||||
|
||||
### 11.2 赛事项目包
|
||||
@@ -613,6 +626,8 @@
|
||||
|
||||
> 大屏的标题字体与正文字体取自「系统设置 → 赛事信息 → 字体」(见 14.3):可选四款内置字体,也可以上传自己的字体;上传字体加载失败时自动回落到默认字体,画面不会出现方块或空白。
|
||||
|
||||
> 除了 Console 开出来的本机大屏窗口,**局域网设备(另一台电脑、电视浏览器)打开 `http://<主机IP>:19540/display` 也能当大屏用**。这类设备会出现在管理端「大屏控制 → 在线大屏」列表里(标记为「局域网浏览器」),也能被单独切页,用法见第 9 节;它们不受 Console 的 kiosk、防熄屏控制(另见常见问题 Q29)。
|
||||
|
||||
### 17.2 轮播与锁定
|
||||
|
||||
- Console 启动的多屏大屏窗口默认**每屏锁定一页**,不轮播;
|
||||
|
||||
+39
-3
@@ -137,8 +137,8 @@ Console 启动的多屏窗口默认每屏锁定一页。到「大屏控制」点
|
||||
|
||||
以前右上角还有一个 `vN` 数据版本号角标,**现在已经去掉,任何情况下都不再显示**。要核对某块屏有没有跟上服务端,看管理端仪表盘「实时连接」里的「版本 N」。
|
||||
|
||||
**Q28:「在线看板」为什么显示未知?**
|
||||
页面上那一块是本地占位节点:系统不按「指令送达」推断大屏是否在线,也不展示每块屏的实际上报状态,所以「在线」列恒为未知,卡片上写着「在线状态未知(占位)」;「最近下发」只是本机下发指令的时间,**不代表大屏在线**。以现场大屏的实际画面为准。
|
||||
**Q28:大屏控制页的「在线大屏」列表显示的是什么?**
|
||||
显示的是**真实**的在线大屏实例,直接读服务端 `GET /api/display/instances`,打开页面时每 5 秒自动刷新一次:本机用 Console 打开的大屏窗口、局域网设备打开 `/display` 连上的浏览器都在里面(后者没有屏号,标记为「局域网浏览器」),每行显示实例 ID、在线 / 离线、当前所在页、来源地址与最后心跳,服务端判定落后时还会多一个「落后」徽标。以前这里确实是本机占位、恒显示「未知」,**那个占位现在已经被真实列表取代了**。离线实例会在服务端保留一段时间;列表读不到时页面提示「读取在线大屏失败」,并保留上一次的结果,不会清空。
|
||||
|
||||
**Q29:安卓电视能用吗?**
|
||||
可以,用电视自带浏览器访问 `http://<主机IP>:19540/display`。但它不受 Console 的 kiosk、防熄屏控制,字体与动画表现以实际设备为准。
|
||||
@@ -219,7 +219,7 @@ Console 启动的多屏窗口默认每屏锁定一页。到「大屏控制」点
|
||||
## 导出与导入
|
||||
|
||||
**Q43:能导出哪些文件?**
|
||||
四类 Excel:总表、全部(多 sheet)、分项成绩表、单位积分明细;另外可导出赛事项目包(zip)与规则包(YAML)。
|
||||
结果导出现在有五类 Excel:**总表**(`总积分榜.xlsx`)、**全部**(`赛事成绩总表.xlsx`,多 sheet)、**全部(单页)**(`赛事成绩总表(单页).xlsx`,单张表平铺)、**分项成绩表**(`分项成绩表.xlsx`)、**单位积分明细**(`单位积分明细.xlsx`);「积分榜」页另有**导出总明细**(`单位积分总明细.xlsx`)与**导出该单位明细**(`单位积分明细.xlsx`)。另外可导出赛事项目包(zip)与规则包(YAML)。
|
||||
|
||||
**Q44:导出文件保存在哪?**
|
||||
浏览器默认下载目录。服务端生成的临时包位于 `data\exports\`,下载完成后自动删除。
|
||||
@@ -361,3 +361,39 @@ Console 启动的多屏窗口默认每屏锁定一页。到「大屏控制」点
|
||||
- 编辑这些运动员时,「所属单位」下拉里没有这个单位,**必须改选另一个单位才能保存**。
|
||||
|
||||
所以更稳妥的做法是:先把名下运动员调到别的单位(或者干脆用「停用」代替「彻底删除」),再决定要不要彻底删除这个单位。
|
||||
|
||||
**Q65:大屏控制页为什么看不到局域网那台电视?**
|
||||
先确认那台设备真的打开了 `http://<主机IP>:19540/display` 并且能连上主机(同一局域网、服务端端口 19540 已放行)。连上后它会出现在「大屏控制 → 在线大屏」列表里——这个列表每 5 秒自动刷新一次,刚打开时等几秒即可。另外注意:
|
||||
|
||||
- 列表里在线实例排在前,离线实例也会保留一段时间(挂在后面),别只看第一屏就以为没有;
|
||||
- 页面提示「读取在线大屏失败」时是列表没读出来,按提示刷新或检查登录状态(该接口需要记录员及以上),不是那台设备没连上;
|
||||
- 本机「显示器」卡片只列**本机接的显示器**,局域网设备没有屏号,不会出现在那张卡片里,只会在「在线大屏」列表里显示为「局域网浏览器」。
|
||||
|
||||
**Q66:怎么给某一块屏单独切页?**
|
||||
在「大屏控制 → 在线大屏」列表里找到那一行,用「当前页」旁的下拉选好页名,点「切到此页」——**只切这一台**,其他屏不受影响。本机显示器也可以直接在「显示器」卡片对应那一行的下拉 + 「切到此页」切。要让**所有大屏一起切**,才用上方「切页」卡片选页后点「立即跳转」。离线实例的下拉和按钮是灰的,切不了。
|
||||
|
||||
**Q67:切页时提示「目标大屏已离线」怎么办?**
|
||||
这条提示只在**点名切页、但一块屏都没收到指令**时出现,说明目标实例已经离线或实例 ID 失效。处理办法:
|
||||
|
||||
1. 在「在线大屏」列表里看那一行的状态与「最后心跳」,确认大屏窗口 / 浏览器还开着、网络正常;
|
||||
2. 等它重连(列表每 5 秒一刷,重连后会变回「在线」)再切;
|
||||
3. 列表里根本没有它时,说明大屏没连上服务端,先解决连接再切页。
|
||||
|
||||
离线实例切不动是正常的:指令发不到它,系统不会谎报「已切换」。
|
||||
|
||||
**Q68:导出里「全部」和「全部(单页)」有什么区别?**
|
||||
两者内容同源,覆盖的都是全部小项的全部报名 / 成绩,区别在排版:
|
||||
|
||||
- **全部**(`赛事成绩总表.xlsx`):一个工作簿里每个小项一张分表(多 sheet),适合归档打印;
|
||||
- **全部(单页)**(`赛事成绩总表(单页).xlsx`):一个工作簿**只有一张表**,把所有单位、所有项目、所有成绩平铺在一起;每行前面带「大项 / 小项 / 组别」三列,脱离分表也能看懂。列是:大项、小项、组别、名次、号码、单位、运动员/队、成绩、积分、状态、备注。适合筛选、排序与二次统计。
|
||||
|
||||
**Q69:怎么把一个单位的积分明细导出成表格?**
|
||||
两种方式:
|
||||
|
||||
1. **只导一个单位**:到「积分榜」页展开该单位的明细,点右侧明细面板头部的「导出该单位明细」,得到 `单位积分明细.xlsx`(逐条列出每一分的来源,末行是「合计」);
|
||||
2. **一次导全部单位**:点「积分榜」页右上角的「导出总明细」,得到 `单位积分总明细.xlsx`——一张带「单位」列的总表,外加每个**有数据**的单位一张分表(没有积分的单位不出分表)。
|
||||
|
||||
团体奖牌榜那一列的「明细」展开的是**同一个单位积分明细面板**,所以也用「导出该单位明细」。另外「导出 → 结果导出」里的「单位积分明细」也能先选一个单位再导出。这些导出都是只读下载,访客也能用。
|
||||
|
||||
**Q70:个人积分榜能导出明细吗?**
|
||||
不能。个人积分榜只有榜单(运动员、单位、个人总分与奖牌数),**没有明细列,也没有对应的明细导出**。需要看某个人 / 某个单位的得分来源时,用「导出总明细」或「导出该单位明细」:记到个人的流水会按折算系数并入所属单位的合计列出(见 Q14、Q18)。
|
||||
Reference in new issue
Block a user