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
+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 启动的多屏大屏窗口默认**每屏锁定一页**,不轮播;
|
||||
|
||||
Reference in new issue
Block a user