Files
AskaEth 9c52dc4b38 feat(display): 大屏「赛事日程侧边栏」(手填日程 + 竖向进度轴 + 热开关 + 每屏覆盖);版本 dev_0.5.16
主人点名要的功能:大屏控制页加一个**可热开关**的侧边栏,在**指定的屏幕**上(不管它当前在哪一页)叠一个
**手填的赛事日程列表**,带**竖向进度条**;日程**不与登记的小项时间关联**、完全手填;竖向时间轴要好看,
**字多时字号自动缩放与换行**要做到位(不能过小、不能过大)。

设计口径(主人逐条拍板):放不下时**围绕当前项开窗**;进度条是**一条竖向时间轴 + 三态节点**;
**深色半透明 + 毛玻璃**;已完成的项**淡化保留**;备注**默认上屏 + 一个总开关**;
明细覆盖层 / 全屏公告期间**自动收起**、结束后自动回来;编辑权限**录入员及以上**;单屏覆盖按**实例 id**。

服务端(走大屏公告那条路 —— PUT /api/settings 是 admin-only,会与「录入员可改」冲突)
- 新增 `schedule` 动作 + 白名单;`POST /api/display/command` 同一个 handler:**先校验 → 再转发 → 最后落库**
  (校验排在转发前,非法配置不会在大屏上闪一帧)
- 落库到赛事库 settings 的 `display.schedule`(**不新建表、不写迁移**,随赛事包走);
  与公告共用那份「写设置键 + bumpVersion」的实现
- **读写不对称容错**:写侧严格 400(含中文提示与第几条),读侧坏数据一律静默当空 —— 老数据 / 手改库不会炸大屏
- 上限:40 条;time ≤20 / title ≤40 / note ≤60(按字符,清洗控制字符);宽度夹 15–40;覆盖 ≤50 条
- 口径收口三处:**时间允许为空**(与管理端同口径)、**showNote 缺键 = true**(区分「键不存在」与「显式 false」)、
  **`inherit` 不落库**(不再白占覆盖预算)

大屏端
- 新增 `ScheduleSidebar.vue` + `schedulePanel.ts`(纯函数:开窗 / 三态 / 整体进度 / 字号与行数 / 按显示宽度截断 /
  单屏覆盖 / 抑制 / 指纹去重)
- 字号是**舞台设计坐标**(1920×1080),靠 `.stage` 的 `transform: scale()` 整体缩放,**不做二次缩放**
  (wiring 断言禁止出现 `window.`/`innerWidth`/`vh`);复用既有的 `fitRowFontPx`(**16–56px 硬上下限**)与 `textEm`;
  固定点迭代 ≤4 轮;**贴下限时宁可行数少也不缩字**;标题 ≤3 行、备注 ≤2 行,超出截断
- 容器 `position:absolute; inset:0; z-index:50`(**不用 fixed** —— `.stage` 带 transform,是 fixed 后代的包含块);
  **独立于 detail 状态机**(goto 会关明细、明细会停轮播,侧边栏必须不受影响)
- 深色半透明 + `backdrop-filter`,并带 `@supports not (backdrop-filter: blur(1px))` 退化为更不透明的深底
- 关着时**不留任何 DOM**(逐字节等同于没有这个功能);`prefers-reduced-motion` 下不做动效

管理端
- 大屏控制页(左列、公告之后)新增「赛事日程」卡片:条目表格(时间/标题/备注/已完成 + 上移/下移/删除)、
  总开关、备注上屏、位置与宽度、**每块屏三态覆盖**(跟随 / 强制开 / 强制关;切回「跟随」会真删掉那条键)
- 保存走 `adminApi.displayCommand`(**不走 admin-only 的设置接口**);本地校验不过**一个请求都不发**
- 排序只有上移 / 下移(该页面禁止挂 pointerdown/mousedown 监听,有既有测试钉着)

测试
- 服务端 16 个包全绿;前端 **1174 例**全过(基线 1096,本批 +78:大屏端 44 + 管理端 34)
- 大屏端另有 **40 项 playwright 实机**(用 `page.routeWebSocket` 假造实时通道):开/关后 DOM 无残留、
  五个页面下都在、`lock=0` 真等轮播翻页且侧边栏不掉、明细与公告期间自动收起并自动回来、
  **1080p 与 4K 字号完全相同**、`reducedMotion` 下无动画;并钉住两条硬指标(真机列表高度 ≥ 纯函数预算、
  容量×行高 ≤ 真机高度)

文档:`docs/升级说明` 新增 `dev_0.5.16`;`使用手册` 9.2 + 17.6;`常见问题` Q108–Q111;`上线检查清单`/`部署指南`
各一条;`devdocs/05·07·13` 同步。

⚠️ 一条**既有边界**(本版故意没改,按主人「兼容性最大化」的要求):导出的名次口径是「通道名次优先」、
屏幕是「成绩行名次优先」,只在「先按决赛计分发布、之后又只更新名次发布一次」这种序列下分叉
(导出显示上次计分的名次)。正常赛程遇不到;遇到时对该组再「按决赛成绩发布」一次即恢复一致。
已写进《升级说明》④ 与《常见问题》Q111。
2026-09-17 20:04:50 +08:00

1402 lines
162 KiB
Markdown
Raw Permalink 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.
# 使用手册
> 面向现场操作人员与管理员。管理面板地址:`http://<主机IP>:19540/admin`;大屏地址:`http://<主机IP>:19540/display`。
>
> 具体按钮文案与页面布局以实际界面为准;本文按当前版本整理。
---
## 1. 角色与权限
系统只有三种身份,权限是包含关系:**管理员 ⊇ 录入员 ⊇ 访客**。
| 身份 | 说明 | 能做什么 |
| --- | --- | --- |
| 访客 guest | 未登录时的默认身份,不需要建账号 | 只读查看积分榜、成绩、基础数据等公开数据;不能录入、发布、改配置 |
| 录入员 recorder | 现场记录员 | 访客全部权限 + 成绩录入 / 存草稿 / 发布 / 撤销发布 / **清空成绩**(4.7)/ 破纪录确认 / 积分调整 / 大屏控制 / 变更历史 |
| 管理员 admin | 赛事管理员 | 录入员全部权限 + 系统设置、用户管理、备份、审计日志、规则包与赛事项目包导入导出 |
> 未登录也能进管理面板,只是所有写操作按钮被禁用,顶部会出现「当前为访客只读视图」提示。
> 个别功能对身份要求更高:「大屏控制」里的**切页、公告、锁定 / 解锁、强制刷新**(走服务端指令)记录员及以上可用;**开窗 / 收窗 / 重新排布**是服务管理程序在本机执行的操作(只在从服务管理窗口打开的面板里可用),不受角色限制;同页的「**实时赛况**」配置(模式与当前项目)属于赛事设置,**只有管理员能保存**——非管理员看到的是整组置灰加一行提示条(见第 9 节)。
### 1.1 登录
1. 打开管理面板地址,进入登录页;
2. 输入账号与密码,点「登录」;
3. 首次登录或密码被管理员重置后,会自动跳到「修改密码」,改完才能继续;
4. 也可以点「以访客身份只读浏览」直接查看数据。
### 1.2 退出
点击右上角用户名旁的**退出**图标,即退出登录并回到只读访客视图。
---
## 2. 界面总览
左侧导航按用途分组:
| 分组 | 页面 |
| --- | --- |
| 总览 | 仪表盘 |
| 成绩 | 成绩录入、成绩审核、破纪录、积分调整 |
| 榜单 | 积分榜、大屏控制 |
| 数据 | 基础数据、导出、变更历史、日志 |
| 系统 | 系统设置、修改密码、关于 |
顶部栏显示:实时连接状态、服务端版本、刷新按钮、当前账号与角色、退出按钮。左侧栏底部有快捷键提示:`Ctrl+Enter` 存草稿、`Alt+Enter` 发布。
**窄窗口 / 手机**:管理面板可以在**窄窗口与手机浏览器**里用(局域网内访问 `http://<主机IP>:19540/admin` 即可)。窄屏下左侧导航收成抽屉(点顶栏的菜单按钮展开)、宽表格可以**横向滑动**查看、对话框不会超出屏幕、按钮与分页的点击区域也放大了,触屏点得中。录入、发布、看榜这些日常操作在手机上都能完成;赛事配置这类操作条目较多,仍建议在电脑上做。
---
## 3. 仪表盘
用于快速掌握全局。上方四张概览卡:领先单位、已发布项目数 / 总项目数、纪录条目数、实时连接状态。
下面一组是四张现场卡片——每个数据源各自独立,**任何一张读不到时只让那一张显示 `—`,不影响其它卡片**:
| 卡片 | 显示什么 |
| --- | --- |
| 今天的小项 | 排期(`scheduledAt`)落在**本机时区的当天**的小项数量与进度(`已发布 X / 共 Y`)。排期为空的小项不属于任何一天;项目列表还没加载完时显示「数据加载中…」,确实没有排期才显示「今天没有排期」 |
| 草稿待发布 | 还没发布的成绩草稿条数(点了「存草稿」但还没「发布」的);读不到时显示 `—`,不会用 0 冒充「一条都没有」 |
| 待确认破纪录 | 状态为**待确认**的破纪录登记条数,点「去确认」跳到「破纪录」页;访客只读时显示「访客只读」 |
| 大屏在线数 | `在线 / 总数`(读在线大屏实例列表)。副标题是**本机管理端的实时连接状态**(本机在线 / 连接中 / 未连接 / 连接中断 / 示例数据)——服务端没有「管理端在线数」这种统计,所以这里如实显示本机状态,不编一个数字出来 |
其余两块:
- 「当前赛程」列出小项及状态(已发布 / 待录入),今天的小项带「今天」标记,点「录入」直接跳到该项目;
- 「实时积分 Top 3」显示前三名与奖牌数;
- 有待录入项目、草稿或待确认破纪录时显示「待办」提醒。
---
## 4. 成绩录入
### 4.1 选择项目与批次
1. 左侧「项目」列表按大项分组,点选要录入的小项;
2. 每个小项带状态徽标:**已发布** 或 **待录入**;
3. 多个组别时,表格上方出现组别页签,切换组别分别录入;
4. 组别页签旁边有**批次下拉**(`全部` / `第 1 批` / `第 2 批` / … / `未分批`),默认 `全部`(`未分批` 只在确实还有未分批的行时才出现)。选某一批后表格只显示那一批的人,方便录入员**只在自己这一批里找名字**,不用在一大堆人里翻;
5. 配了「按队内平均」通道的小项(例如「个人+团体」项目的团体通道),工具栏下方会出现 **「平均值口径」单选**:`只算有效成绩`(没有有效成绩的人不进分母)或 `全部报名人员都计入`(没成绩的按 0 计入平均)。点选后立即保存到该小项,不需要另外点保存;这是小项级设置,该小项的所有组别共用。⚠️ 该小项的聚合口径选了 **「队内最低分」** 时这个单选**对它不起作用**:那种口径取的是队内最差的一份成绩,一个人都没有效成绩的单位一律不参与排名(见 10.4 第 5 条)。
**回到录入页会记住上次录的小项**:离开「成绩录入」页再回来(切到别的页面、去基础数据改点东西、刷新页面),**右侧默认还是你上次录的那个小项**,不用每次重新找。优先顺序是:
1. **地址里带的小项**最优先——从仪表盘「当前赛程」点某一项的 **「录入」** 进来时,就按点的那一项打开(不是上次那项);
2. 否则用**上次录过的小项**——**已发布的小项也算**(发布完回来接着看、接着补录的正是它);
3. 都没有时(换过浏览器 / 清过浏览器数据 / 从没录过)退回原来的默认:**第一个「待录入」的小项**,再没有就取列表第一个。
记忆**只存在本机**(按小项的编号记,与显示名称无关,所以**改小项名称不会影响它**)。**记忆失效时不会挡人**:那个小项被删了、或者浏览器不允许存本机数据(例如隐私模式)时,都会**自动退回上面的默认**,照常进得去。
> 这条修的是一个容易误判的现象:以前回到录入页时**可能被换到另一个小项**(因为默认挑的是「待录入」的,而**刚发布完的小项状态是「已发布」**,恰好被排除),于是「撤销发布」按钮跟着不见了——左栏那项却仍写着已发布。那不是改名弄坏的,是**看的是两个不同的小项**;详见 4.7 与《常见问题》Q102。
**批次录入进度条**:工具栏正下方有一条横跨整行的进度条,显示当前筛选范围的录入进度,例如 `第 2 批 已录 5/8 · 3 条有错`(有错的行既不算「已录」,也会在发布时被防呆拦下,所以要单独报出来);**全部录完时文字变成「已录完 8/8」、进度条变绿**。分母就是当前筛选范围的行数——选了某一批就只数这一批。它和发布防呆、行上的状态徽标用的是**同一套判定**,不会出现「进度条说录完了、发布却说缺人」。
**批次是什么**:层级是 **大项 → 小项 → 组别 → 批次**。批次只是「把一条组别里的人分成几组,方便分批录入 / 分批查找」的**录入与展示分组**——**不参与算分**:名次与积分仍然按「小项 + 组别」整体计算,分批与否不会让分数、名次发生任何变化(评审口径不会变成「按批排名」)。批次筛选也只影响这张表格显示哪些行,不影响发布、积分榜与大屏。
**怎么分批**(三种方式,可混用):
1. **手动勾选**:勾选若干行 → 在「已选 N 行」工具栏里填批次号 → 点 **设为第 N 批**;批次号留空时输入框会提示推荐的**下一个批次号**(已有最大号 + 1),也可直接写新的号;点 **清除批次** 把选中的行改回 `未分批`;
2. **报名表里填**:导入报名表时用可选列 `heat`(正整数,留空 = 未分批),见[报名名单导入规范](./报名名单导入规范.md);
3. **一键均分**:在同一个工具栏里填「每批 N 人」(默认 8),点 **一键均分**——只对**未分批**的行按当前表格顺序切片,批次号接着已有最大号往后排;**已经分好批的行一个都不动**,手工编排不会被冲掉。确认框会先说明将编排多少行、共几批、从第几批到第几批。
> 批次号是 1–999 的整数。切换组别后批次筛选与勾选都会重置(批次是「组别之下」的概念,换组别后旧的批次号没有意义)。
> 分项成绩表与导出**暂不**按批次分块,导出的仍是整组成绩——需要按批查看时,请在「成绩录入」页用批次下拉筛选。
> 团体成绩 = 该单位在本组别所有报名项成绩的平均值(成绩从每个人那一行读),由系统算出来:正常流程是给每个参赛人员各报一条(走 10.7 的「个人报名」),成绩照常录到每个人那一行,团体那一行(如果也报了)不用填成绩。
> 选「全部报名人员都计入」时,只报了单位、一个人都没报(或队员都没成绩)的那条报名也会按 0 进分母,会把该单位的平均成绩拉低;口径与算法见 10.2「大项 / 小项」与 10.4「计分通道」。
### 4.2 录入成绩
表格列依次为:勾选框、录入(状态徽标)、号码、批次、单位、运动员 / 队、成绩输入、名次、状态、积分(自动)、备注、操作。**「运动员 / 队」这一列在姓名后面直接跟着该人的号码布**(灰色小字,例如 `张伟 101`):号码列仍然保留,这一处只是省得在长表格里左右横跳找号。**纯团体报名这一格旁边还有一个「队员」小按钮**(点开登记 / 修改这支队的队员,见 4.13);普通报名没有这个按钮。
**「运动员 / 队」这一列会限宽,长名单可以手动展开**:多人团体项目的队员名单(`张伟(A001)、李强(A002)…`)以前会把整列撑得很宽,现在**收起时限宽**(**14em ≈ 182px**,超出显示省略号);名单够长时(超过 **24 个「显示宽度」**——中文算 2、字母算 1)这一格右侧出现**逐行的「展开 / 收起」**小按钮,点开看全。**个人项目永远不会出现这个按钮**。展开状态**只在本机内存、按报名项记**,换项目 / 刷新即恢复收起;展开那一行会把列略微撑宽(成绩列右移约 **80px**),点回收起就恢复。
**「单位」这一列兼作「成员单位与份额」的入口**:普通报名显示单位简称(或全称)——**这一格与以前长得一模一样**,只是鼠标移上去变成手型、旁边有一行悬停提示,**点一下**会打开「成员单位与份额」弹窗(什么单位参赛、各占多少,见 4.11)。一条报名挂了多个单位(**联队**,两个单位因人数不足合并参赛)时,这一格会多一个「联队」小标,并把成员单位与份额逐条列出来:`联队 第一分公司 50% 第二分公司 50%`;不是均分时还会带上权重,例如 `联队 第一分公司 67%(权重 2) 第二分公司 33%`。**报名的队名**(同一个单位派两个队时写的那个,见 4.12)直接跟在单位名后面显示,例如 `第一分公司二队`;**没填队名时这一格与以前逐字一样**。
| 列 | 操作 |
| --- | --- |
| 成绩输入 | 直接输入成绩;工具栏会提示当前单位(秒 / 米 / 次 / 分),成绩格比过去更宽,四位数也看得全;打字时格子旁边会浮出一个小提示(见下) |
| 名次 | 自动排名项目由系统自动计算,不可编辑;手动名次项目(录入方式为「手动名次」或比较方式为「不比较」)可直接填名次 |
| 状态 | 下拉选择:**有效**、**DNS 弃赛**、**DQ 取消**、**DNF 未完赛**、**退赛** |
| 积分(自动) | 随成绩实时计算,仅供参考 |
| 备注 | 自由填写,示例文本是 `可留空` |
| 操作 | 已发布的行并排两个按钮 **「修改本条」**(退回草稿改一改,改完重新发布本组)与 **「作废本条」**(这一条不算了);已作废的行改显示 **「重新录入」**;草稿行这里是 `—`(草稿本来就能直接改)。详见 4.10 |
> 已发布的行里,**成绩格与状态格可以直接点**:点一下弹出确认框(写明会退回草稿、榜单先把它退下来、改完需重新发布本组),确认后才退回,点「取消」什么都不做。名次格与备注格点不动。
**成绩写法**:能接受的写法比过去多,中文输入法下的全角冒号 `1:06`、全角数字也认。
- 时间类(单位「秒」):`66`、`66.33`、`1:06`、`1:06.33`、`1:6`、`1分06秒`、`1分6秒`、`1分06`、`1小时2分3秒`;
- 距离 / 计数 / 得分类:按工具栏提示的单位填数字,如米 `12.34`、次 `12`、分 `96.5`;
- 秒位 ≥ 60 仍然拒绝(`1:70` 不是 70 秒),但报错会写明原因(见 4.4)。
**打字时的实时提示**:光标停在某个成绩格里打字时,**这一格旁边会浮出一个小提示**,边打边告诉你系统怎么理解它——不用等发布才知道对错。提示分三种:
- **合法** → 直接显示**解析结果**,例如打 `1:06` 显示 `= 66 秒`、打 `66.33` 显示 `= 66.33 秒`(米 / 次 / 分项目显示对应单位),让你确认系统理解的和你想的是同一个数;
- **可疑** → 例如 `成绩 ≤ 0,疑似录入错误`,放行但提个醒;
- **不合法** → 直接说明原因,并**带出那一格的实际内容**,例如 `秒位不能 ≥ 60(当前「1:70」),请写成 1:06 或 66 这类`、`成绩写法无法识别(当前「约1分06秒」),可用 66、66.33、1:06、1:06.33、1分06秒`;
- **空格子不提示**(还没录是正常状态);提示只是浮层,**不接收点击、不占布局、不会改变行高**,继续打字不受影响;靠屏幕底部时提示会自动翻到格子上面显示。
这个提示与发布前的「防呆校验」(见 4.4)**用的是同一套判定**,不会出现「打字时说没问题、发布时却被拦下」这种自相矛盾。
**示例文本不是已填内容**:空格子里显示的 `例 1:06.33`(距离 `例 12.34`、计数 `例 12`、得分 `例 96.5`)是**更淡的斜体灰字**,只是告诉你大概怎么写,**不代表这一格已经有成绩**。灰字不会被提交;点发布时如果那一格还是灰字,就按「还没录」自动跳过(本次不发布这一行),不会连累其他已填成绩的发布。过去示例文本长得和真实输入一样,容易看成「我已经填了」。
**「搜姓名 / 号码布」搜索框(人多项目找人不费劲)**:位置在工具栏 **「批次」下拉右边**。
- **即时模糊匹配**:大小写不敏感、首尾空格与全角空格都当空白;号码布按**数字口径**——`007` 搜 `7`、`7` 搜 `007` 都能找到;
- **命中高亮**(只加一层淡底色);
- 输入框旁边显示 `找到 N 条 / 共 M 条`(**M 是当前批次口径的总行数**,不是搜索结果数);
- 清除有三种:输入框右侧的 × 按钮、在输入框里按 `Esc`、「清除搜索」按钮;搜不到时给明确的空状态与提示,不会只剩一张空表;
- 搜索范围是**行的姓名 / 队员名单 / 队员(含号码布)/ 行号码布**,**不含单位名**;
- **换小项 / 换组别会清空搜索**。
⚠️ 界面上也写着这行小字:**「搜索只影响表格显示,不影响发布范围与进度」** —— 筛完再点「发布」,发的仍然是**该小项 + 该组别里所有已填的成绩**(不是只发筛出来的这些);进度条的「已录 x/y」也仍然是**该批次总人数**。
⚠️ **粘贴跟着屏幕走**:搜索状态下按 `Ctrl+V` 是**按屏幕顺序**往下填的(**被筛掉、看不见的行不会被写到**)——**这是有意的**:否则第二条成绩会静默写到看不见的人身上。要按原来的行序粘贴,请先清除搜索。详见 4.3。
右侧「实时积分预览」显示:若现在发布,各单位积分的变化、最大分差、受影响单位数。
### 4.3 键盘流与批量录入
| 操作 | 效果 |
| --- | --- |
| `Tab` | 跳到下一个单元格(浏览器原生焦点顺序) |
| `Enter` | 在成绩格之间依次移动 |
| `Ctrl+Enter` | 存草稿 |
| `Alt+Enter` | 打开**发布窗口**(与工具栏「发布」同一个窗口,口径在里面二选一,见 4.5) |
| 「按成绩重排」 | 按成绩从小到大 / 从大到小重排表格行(名次仍以比较值为准) |
| 「下一格」 | 按钮方式移动焦点 |
**从 Excel 粘贴**:复制区域后,在成绩格按 `Ctrl+V`。
- 两列及以上:第一列按单位名称 / 简称匹配行,最后一列作为成绩;
- 单列:从当前行开始向下依次填充;
- ⚠️ **搜索状态下按屏幕顺序粘贴**:表格正在按搜索框筛选时,粘贴只落在**看得见的行**上(按屏幕顺序),被筛掉的行**不会被写到**——这是有意的:否则第二条成绩会静默写到看不见的人身上。要按原来的行序粘贴,先清除搜索(见 4.2)。
### 4.4 防呆校验
页面下方「防呆校验」会实时列出问题,分两档:
- **错误(阻止发布)**:只有**会让名次或积分算错**的才挡发布,文案都会**把那一格的实际内容原样打出来**并对症给改法:
- 秒位 ≥ 60:`第 3 行 张三:秒位不能 ≥ 60(当前「1:70」),请写成 1:06 或 66 这类`;
- 写法无法识别:`第 3 行 张三:成绩写法无法识别(当前「约1分06秒」),可用 66、66.33、1:06、1:06.33、1分06秒`——非时间单位会换成对应的数字提示(不会拿时间格式去教距离项目);
- 手动名次项目缺少名次。
- **提醒(不阻止发布)**:
- **成绩还没录**(空格子):`第 3 行 张三:还没录成绩(当前「(空)」),本次发布不计入这一行`。这是中性状态,**不挡发布**——跑完一批就能先发一批,剩下没跑的补录后再发(见 4.6);
- 成绩 ≤ 0、名次重复(请确认是否并列)、成绩与赛会纪录差距过大。
有**错误**时点「发布」会被拦下并提示第一处问题;只有提醒(含还没录的行)时发布会照常进行,未录的行自动跳过。
> 这套判定与打字时格子旁的实时提示(见 4.2)**同源**:输入时看到的解析结果 / 报错原因,与这里、以及发布时的拦截口径完全一致。
### 4.5 存草稿与发布
1. **存草稿**:保存当前组别的成绩,草稿**不会上屏**,也不计入积分榜;有未保存修改时页面会显示「有未保存修改」徽标。
- **未保存的成绩不会被静默丢掉**:有未保存修改时,点左侧菜单切到别的页面(以及浏览器前进 / 后退)会先弹出确认框,确认丢弃才离开;关闭或刷新浏览器时浏览器也会原生提示;切换项目本来就会先确认。选「取消」留在本页,改动都还在。
2. **发布**:点击后弹出**发布窗口**(标题形如 `发布该组:请选择本次的发布口径`),先在**两种口径里二选一**,再点「确认发布」:
| 选项 | 会发生什么 |
| --- | --- |
| **只更新名次(不计分、不发奖牌)** | **默认选中**:名次照常算出来、写进系统,但不产生积分、不发奖牌(分轮次比赛里给预赛 / 复赛用)。选项下面的说明就是 `本次只更新名次:不计分、不发奖牌,榜单分数不变。` |
| **按决赛成绩发布(重算名次并计分、发奖牌、榜单跟着更新)** | 与升级前的「勾上再发布」完全一样:算分、发牌、上榜 |
- 窗口里同时写明本次将发布多少人、还有多少人没成绩;选「按决赛成绩发布」时才会报「影响 N 个单位、最大分差 X 分」(只更新名次时报这两个数是假话,所以不报);
- 确认后这批成绩**立即上屏**:选计分那一项时同时重算积分榜;**只更新名次**时名次照常更新、榜单分数不变(若管理员开了**延迟结算**,则只上屏成绩,名次与榜单等该组录完再更新,见 4.6、10.5);
- **取消 = 什么都不发生**;**每次打开都回到默认那一项**(**不吃上一次的选择**)——这条是故意的:避免「换个小项再点发布,把预赛当成决赛算分」这种最贵的错法;
- `Alt+Enter`(见 4.3)走的是**同一个窗口**;
- 发布前系统会自动把当前内容整组保存为草稿再发布,无需手动先存;
- 示例数据模式下「发布」按钮不可用,避免把未落库的改动当成发布成功。
> ⚠️ **成绩审核页(第 5 节)的入口形状不一样**:那里**仍然是发布按钮旁边的常驻勾选框**(勾上才计分发牌)。两页的口径与算法完全一致,只是录入页把口径挪进了弹窗——别以为审核页也改成弹窗了。
### 4.6 分批发布(跑一批发一批)
跑道只有 8 条、一个项目可能要分好几场跑时,**不需要等所有人都跑完**:每跑完一批就发一批,没跑到的先空着。
1. 这一批跑完,把已出的成绩填上(其他还没跑的行保持空白即可);
2. 点「发布」(该组已有发布过的成绩、且还有没发的已填行时,按钮显示为「**发布本批**」);
3. 确认框会写明:`本组还有 N 人没有成绩,本次将发布已填的 M 人;其余保持未发布,补录后再发布即可。本次影响 … 个单位,最大分差变化 … 分。发布后立即上屏并重算积分榜。`——**看完再确认**,系统只发布已填的那 M 人,不会把没成绩的人当成 0 分发出去(末句在延迟结算下会换成「名次与榜单等该组全部录完后再更新」,见下面);
4. 确认后这批成绩立即上屏;**实时结算(默认)下,名次与积分先按已发布的这部分算**,大屏立刻有内容(延迟结算下先不动,见下);
5. 下一批跑完,回到本页补录成绩,再点一次「发布本批」——系统会把两批放在一起重算名次与积分,先发的部分自动跟着更新;
6. 全部发完后按钮不再显示「本批」(并变为不可用),此时该组视为已全部发布。**只错一条**时不必撤销整组发布,点那一格(或该行的「修改本条」)退回草稿改完重发即可(见 4.10);整组都要改才走「撤销发布 → 修改 → 重新发布」(见 4.7)。
> 只有「会被算错」的写法才会挡住发布(见 4.4);空格子只是「还没录」,属于提醒,不影响发布。审核页(第 5 节)也是同一套口径:只有写错或缺名次才挡「发布整组」,空成绩只是本次跳过。
**如果管理员关掉了「分批发布时实时更新榜单」**(见 10.5),行为会变成这样:发布后**成绩照常上屏,但名次、积分与奖牌榜都不动**——要等**该项目该组所有「正常参赛」的人都录完成绩**才一次性结算并更新榜单(退赛 / 取消资格 / 未出场的人不算在等待里)。未结算期间:
- 录入页在进度条下方显示一条提示:`延迟结算:本组 X/Y 人已出成绩,名次与榜单等该组全部录完后一起更新`(本页预览的名次仍是实时的),旁边就是「立即结算」按钮;
- 该组在**分项成绩 / 最新成绩里的名次显示 `—`**(成绩照常显示)——这是有意的,免得出现「有金牌但 0 分」这种自相矛盾的画面;导出的「分项成绩表」「全部」「全部(单页)」里,这些行的**名次与积分列也是 `—`、状态列写「未结算」**(见 11.1);
- 有人永远录不出成绩时(例如已退赛但没改状态),在录入页点 **「立即结算」**,系统按当前已发布成绩先结算一次榜单和奖牌;之后补录完还会再自动结算。
### 4.7 撤销发布 / 清空成绩(这两个最容易混)
**「撤销发布」和「清空」只差一步:成绩内容留不留。**
| 动作 | 成绩内容 | 已产生的分 |
| --- | --- | --- |
| **撤销发布** | **保留**(退回草稿,改完重新发布即可) | 收回(该组已产生的积分流水作废,大屏回退到发布前) |
| **清空**(清空本组 / 清空本批) | **一起清掉**(成绩、名次、备注、行上的状态全回到「没录过」) | 也收回(同样作废流水、退榜) |
**只想把分收回来、成绩留着改 → 用「撤销发布」;想让这一组 / 这一批回到「没录过」→ 才用「清空」。**
**撤销发布**
已发布的组别会出现「撤销发布」按钮(当前这张表里有已发布的行时才有):
1. 点击后在确认框中确认;
2. 系统作废该组已产生的积分流水,大屏回退到发布前状态;
3. 修改后重新发布即可。全程留痕,可在「变更历史」查看。
> **只错了一条成绩时**,不必撤销整组发布、把别人的成绩也一起翻下来——点那一格(或该行的「修改本条」)退回草稿改完重发即可,见 4.10。
**清空本组 / 清空本批**
用途是**这一组(或这一批)整个录错、要从头再来**。入口在**右侧表格上方那一行工具栏**里(**和「撤销发布」并排**,同一栏还有「补报名」「按成绩重排」「下一格」;「存草稿 / 发布」在更上面的页头):
| 按钮 | 什么时候出现 | 清掉什么 |
| --- | --- | --- |
| **清空本组** | **一直都有**(选了小项与组别之后) | 当前**小项 + 组别**下的**全部**成绩行;以及这一组**按单位录入的「团体名次」**(会一并清掉,否则会出现「成绩都清了、榜上还有分」) |
| **清空本批** | **只在上面筛了某一批次时出现**(筛选是 `全部` 时它等于清整组,所以不重复给) | 只清**当前这一批**的行;**别的批次与团体名次都不动** |
**清空会发生什么**:这一范围里每一行都回到**「没录过」**——成绩、名次、备注,以及行上的**状态**(已标的 `DNS 弃赛` / `DQ 取消` / `DNF 未完赛` / `退赛` 也一并回到「有效」);原先已发布的**分一并收回**,**积分榜与大屏跟着回退**。作废与重算走的是「撤销发布」那条路,所以清完之后榜上剩下的分,与「这些成绩从没发布过」完全一致。
> **报名层面的「退赛」(用 4.8 的「批量退赛」标的)不在这里动**:那个人的报名仍然是退赛,要让他重新算数请用「批量恢复」(见 4.8)。
**清空前必须先勾选**
点按钮会弹确认框,里面写清:**哪个小项、哪个组别、哪个范围**(本组 / 第 N 批 / 未分批)、**清多少条、其中多少条已发布**、已发布的那部分分会一并收回、以及清整组时会不会连带清掉团体名次。**必须勾上「我知道这会清掉已发布的分数」,确认键才点得动**(服务端也会再兜一次,没勾选一律拒绝)。最后一行还写着:**只想收回分数、保留成绩内容,请改用「撤销发布」。**
几个拦下来的情况(都会说明原因,不会静默什么都不做):没选小项或组别;点了「清空本批」但上面筛选还是 `全部`(会提示先选批次);这一范围**本来就没有成绩**(提示「这一范围没有成绩可清空」,多半是看错了批次 / 组别)。
**权限与留痕**
- **清空与录成绩同档:录入员及以上。** 访客 / 未登录时按钮是灰的并写明原因;**示例数据模式**下不可用(与「发布」「撤销发布」同一口径);
- **清空没有「整个小项」这个粒度**——最小就是「组」(或组里的一批),故意的:一颗按钮清掉整个小项所有组别的成绩,爆炸半径太大;
- 谁在什么时候清了**哪个小项、哪个组、哪个范围、清了几条、收回多少分**都会记进**审计日志**(第 13 节,动作名 `result.clear`);**「变更历史」(第 12 节)也会多一个版本节点**并写明清了多少条(它归在「撤销发布」这一类里,因为本质就是撤销发布 + 清内容)。
### 4.8 勾选与批量操作(退赛 / 恢复 / 移出报名)
表格每行最左边有勾选框,表头那个勾选框是**全选当前筛选范围内的行**——它只勾当前组别、当前批次筛选下看得见的行,被筛掉的行不会被选上。勾选后工具栏里出现「已选 N 行」与三个按钮:
| 按钮 | 作用 | 可恢复吗 |
| --- | --- | --- |
| **批量退赛** | 把选中的正常参赛者标记为**退赛(弃权)**:0 分、不占名次 | **可以**,用「批量恢复」撤回 |
| **批量恢复** | 把选中的退赛者改回「正常参赛」 | —— |
| **批量移出报名** | 把选中的报名项**物理删除**,连同他的成绩与积分流水一起删掉 | **不可以**,需二次确认 |
- **批量退赛 / 恢复**会**立即**按新名次重算积分并推到大屏——**延迟结算(见 10.5)也照算**,因为退赛 / 恢复改的是「谁还算数」,不是「录了多少」,名次和分数必须当场跟着改。已经是「取消资格(dq)」「未出场(dns)」的行会被**跳过、不覆盖原判定**(跳过的人会在确认框里逐条列出原因,例如「已被判罚取消资格(dq),跳过」)。
- **批量移出报名**的确认框会列出**将被删除的人**(姓名|号码布|单位,超过 20 人只列前 20 并报剩余数量)以及**将重算的小项与组别**——看完再确认,删了不能恢复;删除后同样**立即重算并推榜**,不受延迟结算影响。
- **移出之后想重新报名**:不用跑回「基础数据 → 报名导入」——录入界面的工具栏右侧就有 **「补报名」** 按钮(和当前小项、组别在同一屏里)。点开后是同一套「从已有名单勾选」界面,并**预选了当前小项与当前组别**;勾选完点「加入报名」,本组名单会立刻刷新,补上的人直接出现在成绩表里。详见 10.7。
- 一次最多处理 **500 条**报名项,超出请分批提交;有未保存的成绩修改时,请先「存草稿」再批量操作;示例数据模式下不能批量操作。
### 4.9 团体名次(按单位录入)
有些项目要按**单位**排团体名次(例如「团体引体向上」),但场上并没有一条"单位自己的成绩"可填——名次是裁判直接给定的。这类项目在录入页会多出一块 **「团体名次」** 卡片。
**什么时候会出现**:只有该组别配了「**团体名次 + 手动名次**」这两项都符合的计分通道时才会出现(通道在「基础数据 → 计分通道」配,见 10.4)。没配这样通道的小项,录入页**不显示**这块卡片——这是正常的,说明它的团体名次另有来源(例如篮球这类纯团体项目,走的是团体报名行上的名次,仍在成绩列表里录)。
**怎么填**:
1. 卡片里按**单位**一行一个输入框(单位清单取「基础数据 → 参赛单位」里启用中的单位,已「彻底删除」的单位不出现);
2. 在单位后面填名次(从 1 开始的正整数);**留空 = 清空该单位的名次**(不需要先填一个 0);
3. 填完点 **「保存团体名次」**;没有改动时按钮是灰的,改了才亮,卡片右上角会显示「未保存」。
**保存后会发生什么**:系统按新名次重算**该组别名次与积分**,并刷新积分榜与大屏(这一步与《个人名次》无关——**个人名次仍然在成绩列表里录**,团体名次只喂给团体通道)。保存完成后会提示「团体名次已保存 · 该组名次与积分榜会按新名次重算」。
**要注意的**:
- **名次重复允许并列**(服务端按积分模板的并列口径处理),但输入框会描红并提示 `名次 N 重复 X 次,允许并列,请确认是否为想要的结果`——确认无误可以照常保存;
- **名次超出参赛单位数**同样会提示(多半是笔误),但**不挡保存**:改不改由你决定;
- **个人名次不受影响**:这块卡片改的是单位,成绩表里每个人的名次、分数一行都不动;
- **中途离开会提醒**:有未保存的团体名次时,切走会有确认框(和未保存的成绩一样);
- **权限**:读得到成绩的人都能看到这块卡片(访客只读,输入框置灰并写明原因);**能保存的是录入员及以上**(与成绩录入同权限)。示例数据模式下不能保存;
- 团体名次是**独立保存**的:点「保存团体名次」只提交这块卡片,不会顺手发布成绩;成绩仍然要另外「发布」。
### 4.10 单条修改 / 作废 / 重新录入(手滑填错了怎么办)
已发布的成绩行在表格里仍然是**锁着的**(名次、备注改不了)——这是有意的:已发布的行已经上屏、已经计分,允许就地改会让「看到的榜单」和「改到一半的数据」对不上。要改就必须先明确地把它退回来。入口有两个,效果一样:
- **直接点那一格**:已发布的**成绩格**与**状态格**点得动,点一下会弹出确认框,写明「这一条会退回草稿、榜单先把它退下来、改完需重新发布本组」;点「取消」**什么都不做**(成绩、榜单、大屏都不动),点确认才退回来。名次格与备注格仍然点不动;
- **点表格最右端「操作」列的按钮**,只有已发布的行才有按钮。
**三个按钮,什么时候用哪个**
| 按钮 | 什么时候出现 | 做什么 |
| --- | --- | --- |
| **修改本条** | 这一行是**已发布且正常**的成绩 | 把这一条**退回草稿**(原来填的成绩还在格里,直接改就行),名次与积分先按「没有这条成绩」重算,改完再发布本组。**只是填错了改用这个**——它不会把这一条标成「已作废」 |
| **作废本条** | 同上 | 让这**一条**成绩不再算数(同组其它人重新排名):成绩文字还留在格里,录入列变成红徽标「已作废」,**不计入名次与积分**。这一条确实不算了才用它 |
| **重新录入** | 这一行是**已作废**的(红徽标「已作废」) | 把这一条**退回草稿**(同「修改本条」),改完就能像普通草稿一样重新发布 |
三个按钮**都必须填写原因**(确认框里的「修改原因 / 作废原因 / 退回原因」),留空时确认键点了也不会提交——原因会写进审计日志,事后能查清是谁、什么时候、为什么动的这一条。
**点完会立刻发生什么**
- 服务端在同一个事务里**按当前已发布成绩重算**该小项该组的名次与积分,并**立即推送大屏**;
- 这一步**不受**「分批发布时实时更新榜单」这个延迟结算开关影响(它改的是「这条成绩算不算数」,不是「录了多少」),不会出现「榜上还有分、成绩却已经撤了」;
- 三个动作都会留痕:**审计日志**(第 13 节)里的动作分别是 `result.void`(作废)与 `result.reopen`(修改 / 重新录入),含操作人、时间与填写的原因。注意「变更历史」(第 12 节)记的是**发布 / 撤销发布**这类整组版本,单条的修改 / 作废 / 重新录入**不会**在那里新增一个版本节点。
**手滑填错了怎么办:三条路**
1. **只错了一条、要改对**(最常见):在那一行点 **成绩格**(或点 **「修改本条」**),确认框会写明后果,填「修改原因」→ 确认:这一条退回草稿、大屏按「没有这条成绩」重算 → **直接改格里的内容** → 再点页头的 **「发布」**(该组还有别的已发布成绩时显示为「发布本批」,见 4.6)。全程只动这一条,同组别人的成绩一直留在榜上;
2. **这一条根本不该算**(成绩无效、重复录入等):同一行点 **「作废本条」** 填原因 → 这一条不再计入名次与积分(成绩文字还留在格里,录入列变成红徽标「已作废」)。以后要让它重新算数,用同一行的 **「重新录入」** 退回草稿改完再发布。**只是填错了用第 1 条**——用「作废」会在榜上留下一条作废痕迹;
3. **整组都要改**(例如整组被判罚、名次口径整体调整):点页面上的 **「撤销发布」** → 修改 → 重新发布(见 4.7)。这条会把该组已产生的积分流水整体作废再重发,大屏会先回退一次。
> 只错一条时**优先用第 1、2 条路**:撤销发布会让整组的分数先消失再回来,大屏在中间会闪一下;单条修改 / 作废只影响这一条。
> 需要先「存草稿」再动这些入口:修改 / 作废 / 退回会重算并整表刷新,未保存的编辑会被刷新覆盖,页面会拦下并提示。
### 4.11 联队(两个单位合并参赛)
有些项目**两个单位因参赛人数不足,合并成一个单位参赛**。这种情况**不要新建一个「联队单位」**——那样榜单会多出一个单位,联队拿到的分与奖牌也分不到原单位头上。正确做法是**一条报名挂多个单位、按份额分成**:榜单仍然是原来的单位数,分数与奖牌按份额记给各单位,联队的名字在大屏与导出件上写全。
**三个口径(赛会已定,录之前先知道)**
| 口径 | 怎么写 |
| --- | --- |
| 份额 | **可配、默认均分**:两个单位各占一半(50% / 50%);要改成别的比例(例如 2:1)就填权重 |
| 积分 | **平均拆,接受 .5**:团体第 1 名 15 分 → 两个单位**各 7.5 分**(榜单上就写 7.5) |
| 奖牌 | **每个成员单位各记一枚整枚**:联队的金牌,两个单位**各记 1 枚**(不是各 0.5 枚) |
> ⚠️ 由此产生一个**必须知道**的结果:**各单位的奖牌数之和会大于实际颁发的奖牌数**。A、B 联队拿 1 枚金牌,奖牌榜上 A 记 1 金、B 记 1 金,而场上只颁发了 1 枚。**这是定稿口径,不是数据错了**;拿奖牌数去和实际颁发的奖牌核对时请记住这一点。导出件的「总表 / 单位奖牌明细」副标题里也写着这句话。
**怎么配(两个入口)**
1. **导入报名表时**:把「单位编码」那一格写成 `A+B`(例如 `F1+F2`)——**加号左边那个是主单位**(名次与榜单的归属主体),全角 `+` 与两侧空格都认。默认均分;一个联队最多 5 个单位。写法与报错见[报名名单导入规范 · 第三节](./报名名单导入规范.md);
2. **导入之后在界面上改**:到「成绩录入」页**点那一行的「单位」格**(复核页只读,改份额在录入页),打开「成员单位与份额」弹窗。要改成非均分(例如 2:1)**只能在弹窗里改,导入表里写不了**。
**「成员单位与份额」弹窗怎么用**
1. 弹窗里每个成员单位一行:**编码 / 单位全称 / 「主单位」徽标 / 权重输入框 / 移除**;
2. 权重是**相对权重**:都留空(或填 0)就是**均分**(各 50%),填 `2` 与 `1` 就是 **67% 与 33%**;
3. 底部「**添加成员单位…**」下拉里选一个单位再点「添加」——下拉里列的是还没在成员里的单位(**已停用**的单位也可以加,会标注「已停用」;被「彻底删除」的单位不出现);
4. 弹窗下方实时显示 `当前比例:第一分公司 50% · 第二分公司 50%`,两个以上成员时旁边还会给出联队名预览(`第一分公司+第二分公司联队`);
5. **主单位不能去掉**(它的「移除」是灰的):报名挂在它名下,要换主单位只能重新建报名;
6. **纯团体报名还会多一个「队伍」输入框**(同一个单位派两个队时写队名,见 4.12):**只有纯团体报名显示这个框,个人报名连框都不出现**;留空 = 不区分队伍。它与份额是**两个接口**,改队名**不会重算榜单**(队名只是标签);
7. 点 **「保存成员单位」** 提交——服务端**当场重算该小项该组别**的名次与积分并刷新大屏榜单,提示「成员单位已保存」。**没改动时保存按钮是灰的**,点「关闭」不会发出任何请求。按钮上的字会按你改了什么变:只改队名时是 **「保存队伍」**、只改份额时是 **「保存成员单位」**、两样都改了是 **「保存成员单位与队伍」**。
**要注意的**
- **权限**:读得到成绩的人都能看见这一格;**能改的是录入员及以上**(与录成绩同档)。访客只读时输入框置灰,并写明「当前为访客只读视图」或「服务端未连接」;示例数据模式下不能保存;
- **普通报名完全不受影响**:只有一个单位的报名,这一格的文案、元素与以前一样,**不改动就不会发出任何请求**;
- **分数怎么分、牌怎么记**:保存后这条成绩的分按份额拆给各成员单位(榜单上各处都已经是拆后的数),奖牌**每个成员单位各记一枚**(见上面的口径表与那句提醒);
- **按单位导出名单时,成员单位也看得到这条报名**:用 B 单位筛「报名名单」,能看到主单位是 A、成员里有 B 的联队报名——否则 B 导出自己的名单会发现「没派人上场」;
- ⚠️ **个人积分总明细里,联队里的同一个人会出现两行**(引擎按份额给两个成员单位各留一行流水)。导出侧只在「来源」列写清这两行为什么出现(`成绩(联队分拆:…)`):**看两行加起来才是这个人的总数**,他的总分没有被算两遍;
- ⚠️ **团体名次(见 4.9)要录在「主单位」那一行**:联队的名次录在主单位上,系统才会按份额拆给各成员单位;**不要再给成员单位单独录一份名次**,那会让成员单位再拿一份分(重复计分)。
- ⚠️ **「按队内平均」这类聚合通道的项目,联队不拆份额**:这类通道的名次不对应任何一条报名,分仍记在主单位头上(本轮如此)。要保证联队一起算,请用不聚合的口径(或按 4.9 在主单位上录名次)。
- 一件事只做一次:**同一个小项同一个组别里,两个单位联合参赛就写一条 `A+B` 的报名**。`A+B` 与 `B+A` 是**两条不同的报名**(主单位不同),不要两种写法都填。
### 4.12 团体项目多队(同一个单位派两个队)
**羽毛球双打那种:一个单位在同一个组别报了两支队**(例如一队、二队),两队可能各占一个名次。系统支持这么报——**不用新建单位、也不用重复报两次**,两队各算各的成绩、名次与积分,最后都汇到同一个单位的总分上(一个单位两个队都进前三时,这个单位拿 **2 枚牌**)。
**只对团体项目**:个人项目(按人报名的那些)不受影响,也没有「队」这回事。
**怎么录(三条路,任选)**
| 方式 | 怎么做 |
| --- | --- |
| **导入报名表** | 用**最后一列「队伍」**写队名:一队那行写 `一队`、二队那行写 `二队`(同一个单位、同一个组别写两行)。**只有一支队的单位这一列留空**;不填这一列、表头里没有它,都合法。列名与报错见[报名名单导入规范 · 第三节的「队伍」](./报名名单导入规范.md)——⚠️ **导入表由 12 列变成 13 列,但老 12 列表照常导入**(新列加在最后,一列都不会错位) |
| **补报名(勾选)** | 在「成绩录入」页工具栏点 **「补报名」**(或「基础数据 → 报名导入」的**团体报名**页签):勾上某个单位后,**那一行右侧会出现「队伍(留空=不区分)」输入框**,填队名即可;**没勾的单位不显示这个框**。已经报过的单位徽标会写成 `已报名(一队、二队)` |
| **改队名** | 队名填错了**不用删掉重建**:到「成绩录入」页**点那一行的「单位」格**,打开「成员单位与份额」弹窗,里面有 **「队伍」输入框**(**只有纯团体报名才显示**,个人报名连框都不出现)。改完点保存——按钮会按你改了什么都写明(`保存队伍` / `保存成员单位` / `保存成员单位与队伍`),**没改动时按钮是灰的** |
**显示成什么样**
- **`单位名 + 队名`,不加括号、不加分隔符**:`第一分公司一队`、`第一分公司二队`;**队名留空时仍然只写 `第一分公司`**(与以前逐字一样);
- 出现的地方:**成绩录入页 / 成绩审核页的「单位」列、批量操作的确认框、报错里的行名、大屏的分项成绩 / 实时赛况 / 底栏「最新完成项目」,以及导出件的「单位」列**(分项成绩表、全部成绩单页、报名名单、单位奖牌明细总表、单位积分总明细总表);
- **单位总分榜、单位奖牌榜、个人积分榜上不写队名**(它们的单位名来自单位汇总,分与奖牌本来就归到单位)。
**要注意的**
- **同一个单位、同一个组别、同一个队名只能有一条**:要派两支队就得写**两个不同的队名**。两个队名写一样(或都留空)时,第二行会被**逐行拦下**并说清是哪个单位、哪个队(见导入规范的第六节);
- **队伍只对团体行生效**:个人行(有姓名的那几行)**填了队名也不会写进库里**,导入结果里会给一条提示说明这一格被忽略了;
- ⚠️ **改完队名之后,记得把报名表里的队名也改掉**:导入是按「小项 + 组别 + 单位 + 队名」认人的,以后再导一份**还写着旧队名**的表,会**新增出旧队名那一条报名**(不会静默合并);
- **改队名不影响成绩与榜单**:队名只是给现场看的一个标签,不参与名次、积分、奖牌的计算,所以改它**不会重算榜单**,也**不会给别处的大屏 / 录入页推刷新**——别的窗口要等下一次刷新才看到新队名(你自己那一次保存的页面上会立刻变);
- 队伍**不参与「团体名次」按单位录入**的那一类项目(篮球那种每个单位只有一支队):名次仍然是按单位录的,与队名无关。
### 4.13 团体报名的队员(谁在这支队里)
**团体/对抗项目(双打、接力、拔河、篮球…)的报名上可以挂「队员」**——挂上之后,系统知道**这支队伍里坐着谁**。这条报名在配了「个人通道」的项目里就会**给每个队员各发一份完整的个人分、各一枚个人奖牌**,他们也因此能上**个人积分榜**(过去只存一串姓名文字,谁都上不了个人榜)。
**「每人各一份」不是「几个人分同一份」**:一对双打赢了拿 10 分,是**两个人各 10 分**(不是各 5 分)——这与「联队把分拆给几个单位」正相反。**单位总分与单位奖牌不受影响**:一个单位拿到多少分、多少牌,由「计分通道」里的 `计入单位总分` / 个人奖牌是否并入单位榜两个开关决定;**双打现场通常都设成不计入**,也就是个人分给到人、单位那本账不变。
**怎么挂队员(三条路)**
| 方式 | 怎么做 |
| --- | --- |
| **补报名时勾人** | 「成绩录入」页工具栏的 **「补报名」**(或「基础数据 → 报名导入」的**团体报名**页签):勾上单位后可以**登记队员**(逐个勾选,可按姓名 / 工号搜索)。**勾上的人会真正提交上去**,写进那一条团体报名 |
| **录入页改队员** | 「成绩录入」页表格里**「运动员 / 队」那一格旁边的「队员」小按钮**(**只有纯团体行才有**)→ 打开勾选式名单(带搜索)→ 勾完保存。这是**把已经报过的报名补挂 / 改挂队员**的地方 |
| **导入报名表** | 把「队员名单」那一格写成**号码布**(例如 `101/102`),导入时会自动关联到人;**写姓名只当文字**,详见[报名名单导入规范 · 第三节「队员名单」](./报名名单导入规范.md) |
**号码布是唯一标识**
- 系统**只按号码布认人**(`101` → 号码布是 101 的那个人)。**姓名一律不参与匹配**——同名会认错人,而认错的分已经上了榜;
- 所以**「队员名单」里只写姓名是拿不到个人分的**(名单照常显示,也**不报错**);界面上手动勾人不受这条限制(勾的是人);
- 号码布认到的是**别的单位**的人时**照常关联**,并给一条提示让你核对号码布是不是抄错了(号码布是唯一标识,系统不看单位)。
**显示成什么样**
- **导出件(指给人看的报表件)**:一个队员写 **`姓名(号码布)`**(例如 `张三(101)`),多个用 `、` 连——报名名单的「姓名」列、分项成绩表 / 全部成绩单页 / 单位奖牌明细的「运动员 / 队」列都这样;**个人得分明细里每个队员各占一行**(双打就是两行,各一整份分)。⚠️ 例外是「导入格式」那两份(见 11.1):它们按导入口径写——**团体行的「姓名」列留空**,队员在「队员名单」列(多个用中文逗号 `,` 分隔);
- **大屏**:分项成绩 / 实时赛况的运动员列、底栏「最新完成项目」的名字格都会带上队员名单(**只写姓名**,号码布太长会把整屏字号压小);
- ⚠️ **一条报名仍然只占一行**,不会因为挂了两个队员就变成两行(队里的两个人是**一条报名**里的两个身份);
- ⚠️ **队名(4.12)与队员是两件独立的事**:单位列照旧显示「单位名 + 队名」,队员只出现在运动员列 / 底栏。
**老数据怎么办**
- 升级时会**尽力回填**一次:拿原来那串姓名文字去对——**先按号码布认**,再按「姓名 + 单位」(**同一个单位同名的人只有一个**时才认);**认不上的就留空**(不硬猜,避免把分记到别人头上);
- 所以**升级后请抽查几个团体报名**:只写姓名(或没写队员)的老报名,很可能**还是没有队员身份**——需要的话,到录入页点「队员」按钮手动挂上,或重新导入一份**写着号码布**的报名表;
- ⚠️ **改完队员之后**:这条报名的个人分、个人奖牌会**当场重算并推榜**;但**名单文字(`member_names`)与队员关联是并存的**——名字文字里没被认成人的那些名字**永远上不了个人榜**,要上榜就得挂成队员。
**要注意的**
- **权限**:读得到成绩的人都能看见;**能改的是录入员及以上**(与录成绩同档)。访客只读时按钮置灰;示例数据模式下不能保存;
- **一条报名最多 30 个队员**(超过会被拦下,多半是号码布写错了位置);**个人报名(按人报的那些)没有队员**(它自己就是那个人的身份);
- **改队员不会重算整张榜**(与改队名一样只重算这条报名所在的组别),**也不会给别处的大屏推刷新**——别的窗口要等下一次刷新才看到新名单。
---
## 5. 成绩审核
用于在发布前统一复核草稿。
1. 左侧「待审草稿」按「小项 + 组别」分组,显示每组草稿条数,可搜索小项 / 组别 / 单位;
2. 点选一组后,右侧显示该组成绩明细(单位、运动员 / 队、成绩、名次、状态、积分);
> 「单位」这一列与录入页同一口径:普通报名显示单位简称;**联队**(一条报名挂多个单位)会多一个「联队」小标,并把成员单位与份额逐条列出(`第一分公司 50%` / `第二分公司 50%`),悬停能看到联队全名——复核时一眼就看出这一条其实是几个单位合并报的。本页只读,改份额请到「成绩录入」页点那一行的「单位」格(见 4.11)。
3. 用「整组对比 / 逐条对比」切换,查看发布后各单位积分的变化;
4. 「发布影响」列出受影响单位与分值变化;
5. 操作:
- **发布整组**:确认框会写明本组还有多少条没有成绩、本次将发布已填的多少条;确认后**只发布已填的那部分**并重算积分榜(延迟结算下同样等该组录完才更新名次与榜单),没录的保持未发布,补录后再发一次即可(分批发布,见 4.6);
- **退回**:当前版本服务端没有「退回」接口,此操作**仅在管理端本地标记**,不会改动成绩数据;刷新页面后标记可能消失。如需真正退回,请通知录入员到「成绩录入」修改后重新保存。
> ⚠️ **本页的发布口径入口与录入页不同(两页别混)**:**本页保持原来的常驻勾选框** —— 发布按钮旁边的 **「以决赛成绩发布(勾选才计分发牌)」**,**默认不勾**,勾上才计分、发牌;旁边徽标随时显示当前是哪种口径(**只更新名次(不计分)** / **计分发布(算分发牌)**)。**录入页(4.5)则是点「发布」后在弹窗里二选一**(默认「只更新名次」)。两页发出去的请求口径完全一样,只是入口形状不同。
> 草稿态永远不会上屏;发布以「小项 + 组别」为一组整体生效,但**没录成绩的条目会被跳过**——它既不挡发布,也不会被当成 0 分(防呆口径与录入页一致,见 4.4)。
---
## 6. 破纪录
页面顶部会显示破纪录加分开关状态(来自规则包 `recordBonus.enabled`)。当前版本默认关闭;若当前角色读不到规则包,会如实显示「未知」,以服务端校验结果为准。
### 6.1 疑似破纪录与「已批准的破纪录」
- 系统用**已发布且有效**的成绩与当前纪录自动比对,推导出疑似破纪录,草稿不参与;
- 列表显示小项、组别、单位 / 运动员、成绩、原纪录、档位(赛会 / 市级 / 省级 / 全国)、预计加分;
- **确认加分**:登记破纪录并生成加分流水、更新纪录库;开关关闭时按钮不可用;
- **拒绝**:判定这条不是破纪录时点它。系统会**在服务端先登记一条破纪录记录、再立即驳回**(原因固定写「现场判定不是破纪录」),所以**刷新后不会再出现在待确认列表里**,谁在什么时候否掉了哪一条也能在日志里查到。示例数据模式或后端未就绪时只在本机隐藏,提示会如实说明「刷新页面后该条会重新出现」。
#### 已批准的破纪录(批错了可以撤回)
「已批准的破纪录」卡片列出所有**已批准**的登记。这条接口**需要录入员及以上**才能读(含待审核的登记与驳回理由);访客只读时卡片会写明「访客只读:看不到破纪录登记」,不会假装成「一条都没有」。
每行显示小项、级别、成绩、加分、批准时间、说明,右端有:
- **作废**:批准时已经加过分,所以作废不只是改状态。点它会弹确认框,写明「作废后将撤回该笔加分,并恢复该级别的上一条纪录;大屏与此处纪录库会立即更新」,并要求填 **「作废原因」**(必填,留空点确认不会提交)。确认后服务端在同一个事务里**撤回该笔加分、重算并推榜、把该级别的当前纪录恢复为上一条**,完成后提示「加分已撤回,该级别纪录已恢复上一条」。
- 如果该级别本来就没有更早的纪录,撤下后就留空——「无纪录」是事实,不会留一条刚被作废的纪录充数。
> 待确认的登记被驳回不涉及加分与纪录,服务端只改状态、记理由,不会白重算一次榜单。
### 6.2 纪录库
- 按小项分组展示,可用「全部 / 赛会 / 市级 / 省级 / 全国」页签筛选,也可搜索小项或保持者;
- 每行显示档位、成绩、保持者、单位、达成时间、**来源**以及是否为当前纪录(当前纪录带「当前」绿标);
- **「来源」列的含义**:
- **历史** = 赛前手工登记的旧资料(用下面的「新增历史纪录」录进来的);
- **本届** = 本场赛事批准破纪录时系统自动写入的;
- 读不到时显示 `—`(旧服务端不下发这个字段时不会冒充成「历史」)。
#### 新增历史纪录
点「纪录库」卡片头部的 **「新增历史纪录」**(**录入员及以上**;访客只读时按钮置灰并提示「访客只读,无法新增」):
1. 选 **小项**(必选);
2. 选 **级别**:赛会 / 市级 / 省级 / 全国(默认「赛会」);
3. 填 **成绩值**(数字,例如 `11.2`)和 / 或 **成绩文本**(例如 `11.20`、`1:06.33`)——**两者至少填一个**,都填时比较与破纪录判断以成绩值为准;老秩序册上常常只有其中一种;
4. 可选填 **保持人姓名**、**保持单位**(不指定就留空;很多历史纪录已经查不到人是谁,留空是正常的,不会逼你编一个名字)、**创造日期**(日期选择器,可留空);
5. 点 **「保存纪录」**;成功提示「已新增历史纪录 · 来源记为「历史」」。
新录入的这条会成为该小项该级别的**当前纪录**,原来那条自动变成非当前(但仍留在库里,来源与达成时间不变)。
#### 删除
每行右端有 **「删除」**(同样需要录入员及以上):
1. 确认框会写明将删除哪一条(「将删除「小项」的「级别」纪录 X;若它是当前纪录,会恢复上一条。」),并注明「删除只影响纪录库,不会改动任何已发布的成绩与积分」;
2. 点 **「确认删除」** 后:删掉这一条;如果删的正是当前纪录,服务端会把该级别的**上一条恢复为当前**;一条都没有就把该级别留空;
3. 删除**不会**重算名次与积分——它只动纪录库本身。
---
## 7. 积分调整
用于人工加减分,全程留痕。
页面顶部显示人工调整开关状态(规则包 `manualAdjustment.enabled`)。若已关闭,「新增调整」按钮不可用。
### 7.1 新增调整
点「新增调整」,填写:
| 字段 | 说明 |
| --- | --- |
| 单位 * | 下拉选择参赛单位 |
| 分值 * | 正数加分、负数扣分,不能为 0 |
| 类别 * | 处罚 / 补分 / 更正 |
| 关联项目 | 可选,关联到具体小项 |
| 理由 * | 必填,会写入审计日志 |
保存后积分榜实时更新。
### 7.2 查看与作废
- 列表可按类别筛选、按单位或理由搜索,分页浏览;
- 点某行的「作废」,填写作废理由并确认,对应积分流水会一并作废;
- 已作废的记录仍保留在列表中,状态显示「已作废」。
---
## 8. 积分榜
顶部页签:**单位总分榜**、**单位奖牌榜**、**个人积分榜**;右侧搜索框可按单位或运动员过滤。
### 8.1 单位总分榜
- 列:名次、单位、总分、金、银、铜、变化、明细;
- 「变化」列显示名次升降(如 `↑2`、`↓1`);
- 点「展开」下钻该单位的积分明细,右侧面板显示合计与每一条得分来源(项目 / 组别、运动员、来源、成绩、名次、积分),每一分都可溯源;
- **「运动员」列**:团体项目、按队内平均算出的团体分、以及人工调整这几类没有单个运动员的明细,这一列显示**单位名**(单位的团体分就是该单位挣的);人工调整没有项目也没有运动员,显示 `—`;
- **「来源」列**:这一分是怎么来的——`成绩`(正常计分)、`破纪录加分`、`人工调整`,与导出的「来源」列用词一致;
- **被改过的成绩带一个「已修订 ×N」小角标**(N = 发布后被改过的次数),鼠标悬停在角标上会显示**最后一次修订的时间、原因与操作人**;没改过的行没有角标。
### 8.2 单位奖牌榜 / 个人积分榜
- 单位奖牌榜显示金、银、铜与合计;
- ⚠️ **有联队(两个单位合并参赛)时,各单位的奖牌数加起来会大于实际颁发的奖牌数**——联队的每一枚奖牌**每个成员单位各记一枚整枚**(A、B 联队拿 1 枚金牌,榜上 A 记 1 金、B 记 1 金,场上只颁发了 1 枚)。**这是定稿口径,不是数据错了**;拿榜单去和实际颁发的奖牌核对时请记住这一点。联队本身怎么配见 4.11;
- **单位奖牌榜有自己的名次与顺序:金牌多的在前,其次比银牌、铜牌,最后按单位编码排**——它不看总分,所以「金牌多但总分低」的单位在这里排在前面,在单位总分榜上却靠后,这是口径不同,不是数据错了;
- 个人积分榜显示运动员、单位、个人总分与奖牌数;
- 单位奖牌榜那一列的「明细」展开的是**同一个单位积分明细面板**(见 8.1),不是奖牌专属明细;但这份榜单本身有专属的逐枚奖牌导出(见 8.3);
- 个人积分榜**没有明细列**(不能点开下钻),但它的逐条得分来源也有专属导出(见 8.3)。
### 8.3 导出明细(xlsx)
- 三个榜单的**卡片头**各有一个导出按钮,按钮跟着当前页签切换;展开某个单位时,右侧明细卡头还有 **导出该单位明细**;
- **导出总明细**(单位总分榜卡片头):导出 `单位积分总明细.xlsx`——一张带「单位」列的总表,外加每个**有数据**的单位一张分表;没有积分的单位不出分表;
- **导出奖牌明细**(单位奖牌榜卡片头):导出 `单位奖牌明细.xlsx`——第一张总表逐枚奖牌列出「单位 / 大项 / 小项 / 组别 / 名次 / 奖牌 / 运动员、队」,`奖牌` 列是 `金牌` / `银牌` / `铜牌`;其后每个**有奖牌**的单位一张分表(列同上、去掉「单位」,末尾一行小计 `金 X / 银 Y / 铜 Z`),没有奖牌的单位不出分表。口径与「单位奖牌榜」一致:同一个报名项在「个人+团体」这类双计通道下只记一枚奖牌,不会重复计数;
- **导出个人明细**(个人积分榜卡片头):导出 `个人积分总明细.xlsx`——第一张总表逐条列出「单位 / 运动员 / 大项 / 小项 / 组别 / 名次 / 成绩 / 得分 / 来源」;其后每个**有得分**的单位一张分表(按单位分,不按人分),没有得分流水的人不出现在表里。`得分` 是记到个人的原始分,**与「个人积分榜」逐个数字一致,且不乘榜单口径里的个人项目得分折算系数**(那个系数只作用于单位总分);
- **导出该单位明细**(右侧单位明细面板头部):先展开某个单位再点,导出 `单位积分明细.xlsx`(列:序号、大项、小项、组别、运动员、名次、成绩、来源、积分、备注,末行是「合计」)。**备注列会写下修订痕迹**:被改过的成绩写「已修订 ×N;最后一次 <时间> <原因>」,没改过的行留空——与屏幕上那个角标是同一句话,事后拿表格对账不会对不上。单位奖牌榜展开的也是这个单位积分明细面板,所以想按单位逐条看时同样用它;
- **联队(一条报名挂多个单位)在这几份导出件里怎么体现**(见 4.11):
- **单位积分明细 / 单位积分总明细的「备注」列**:这一条是从联队分来的,会写清分给了哪些单位、各拿多少分(多少 %),例如 `联队分拆:第一分公司 5 分(50%)、第二分公司 5 分(50%)`;「积分」列写的是**本单位实得的那一份**(上例是 5 分,不是联队拿到的 10 分);
- **个人积分总明细的「来源」列**:这一条是联队分来的写成 `成绩(联队分拆:第一分公司 5 分(50%)、第二分公司 5 分(50%))`。⚠️ 这张表里**联队成员会出现两行**(引擎按份额给两个成员单位各留一行流水)——**看两行加起来才是这个人的总数**,他不是被算了两遍;
- **单位奖牌明细的「奖牌」列**:联队那一枚写成 `金牌(联队 第一分公司+第二分公司,各单位各记 1 枚)`(非联队行仍然只有「金牌」两个字)。为了让这句话写得下,这一列**加宽并允许换行**,格子里的值本身没变;
- **总表 / 单位奖牌明细的副标题**:赛事里有联队时,会追加一句 `· 注:本赛事含联队,奖牌按「每个成员单位各记 1 枚」统计,各单位奖牌数之和会大于实际颁发数`——**各单位奖牌数加起来比实际颁发的多,是定稿口径,不是数据错了**(A、B 联队拿 1 枚金牌,两边榜上各 1 枚);
- 这些导出都是只读下载(访客也能用),不需要写权限;导出过程中按钮会变成「导出中…」并禁用,避免重复下载。
### 8.4 推送明细到大屏
1. 展开某个单位的明细;
2. 点「推送到大屏」;
3. 所有大屏会弹出半屏明细覆盖层,**60 秒后自动关闭**;
4. 想立即关闭,点页面顶部「关闭大屏明细」并确认。
---
## 9. 大屏控制
| 区块 | 操作 |
| --- | --- |
| 切页 | 选择「总积分榜 / 单位奖牌榜 / 个人积分奖牌榜 / 分项成绩 / 实时赛况 / 公告」,点「立即跳转」(**所有大屏一起切**);只想切某一块屏或某台设备,用右侧「在线大屏」卡片里那一行的下拉与「切到此页」 |
| 锁定与刷新 | **锁定**:停止自动轮播并停在当前页;**解锁**:恢复轮播;**强制刷新**:让所有大屏重新拉取快照,用于排障 |
| 公告 | 输入公告文字,设置「滚动时长」(5–120 秒,实际是全屏展示的秒数),点「推送公告」;点「清除公告」撤下当前公告 |
页面顶部徽标显示当前是「轮播中」还是「已锁定」。
> 「**单位奖牌榜**」这一页旧称「**团体奖牌榜**」(容易和「团体项目的奖牌」混淆,所以改名),大屏上、切页下拉里现在一律显示「单位奖牌榜」;旧名仍被当作别名接受,老的大屏地址与老配置(`display.pages`)不需要改。
> **权限**:本页的**切页、公告、锁定 / 解锁、强制刷新**(服务端指令)记录员及以上都能用;**开窗 / 收窗 / 重新排布**由服务管理程序在本机执行,不受角色限制(该卡片只在从服务管理窗口打开的面板里可用);只有「实时赛况」卡片(模式与当前项目)属于赛事设置,**仅管理员能保存**,非管理员看到的是整组置灰 + 一行提示条。
**公告**:点「推送公告」后所有大屏先**全屏**展示这条公告,到时间后自动退回原来的页面(没锁定就继续轮播),公告正文留在底栏的「公告」槽位继续显示,直到被新公告替换或点「清除公告」。公告卡片顶部徽标显示「当前公告:有 / 无」,徽标下面那一行就是当前公告正文(没有公告时显示「暂无公告(大屏底栏显示占位)」)。公告会随赛事设置保存:新开的大屏窗口、断线重连之后,会先把当前公告再全屏播一遍(默认 15 秒)后留在底栏;点「清除公告」后底栏回到「暂无公告」占位。
**实时赛况**:「实时赛况」卡片决定大屏「实时赛况」页显示哪几个项目(**最多 2 个**)。
- **自动判定 / 人工指定**:卡片右上角徽标显示当前模式。选「自动判定」时按三条依据依次判定——**人工指定 → 排期命中(项目开始时间前后 30 分钟内)→ 最近发布过成绩的项目**;选「人工指定」时只显示下面指定的项目,不做任何回退;
- **项目 1 / 项目 2** 两个下拉:从当前赛事的小项里选(选项里有「未指定」),已选的行可以「清除」;同一个项目不会重复占两个槽位;
- **当前生效**:显示此刻大屏实际会显示的项目与入选原因,格式如 `男子 100 米(排期命中)`;没有可显示的项目时显示「当前没有可显示的项目」。旁边的「刷新」只重新读取,不改配置;
- **保存**:改完模式或项目后点「保存」,提示「实时赛况设置已保存」后大屏按新配置显示;卡片底部注明「当前项目最多 2 个」;
- 该卡片的「保存」需要**管理员**身份(见本节开头的权限说明);示例数据模式下不能保存。
**赛事日程**:左列「公告」卡片下面那张「赛事日程」卡片,把**手填的日程**做成大屏上的一条**竖向进度轴侧边栏**(**可热开关**,叠在大屏**当前页之上**,不影响轮播)。**录入员及以上**就能改。卡片每一项怎么填、大屏上长什么样、什么时候会自动收起,见本节 **9.2**;大屏侧的观感与行为另见 **17.6**。
**在线大屏**:右侧「在线大屏」卡片列出的是**真实**的在线实例,直接读服务端 `GET /api/display/instances`,打开页面时每 5 秒自动刷新一次(浏览器切到后台时暂停,切回来立刻补一次)。每个实例一行,显示**设备名**、在线 / 离线徽标、「局域网浏览器」或「屏 N」标记、当前所在页、来源地址与最后心跳;服务端判定某个实例落后时还会多一个「落后」徽标(大屏可能在卡或网络差)。**本机用 Console 打开的大屏窗口、以及局域网设备打开 `/display` 连上的浏览器,都会出现在这里**——局域网浏览器没有屏号,那一栏显示「局域网浏览器」。离线实例会在服务端保留一段时间,方便排查它是什么时候掉的。
**设备名怎么来的(自动标签 + 手动改名)**:局域网浏览器连上来时会报一个**自动设备标签**,形如 `安卓 13 · Chrome 120 · 1080×2400 @3x · 手机`,写法是 **系统 + 版本 · 浏览器 · 分辨率 · 形态(手机 / 平板 / 桌面)**,某个段取不到就跳过(例:`iPadOS 17 · Safari 17 · 2048×2732 @2x · 平板`、`Windows 10 · Edge 120 · 1920×1080 · 桌面`、`安卓 13 · 微信 8 · 1080×2340 @2.75x · 手机`)。
- ⚠️ **自动标签认不出「哪台机器」**:浏览器**没有**读主机名 / 设备名的 API(这是安全边界),所以**拿不到 `XIAOMI-PAD-05` 那种真机名**;`model` 字段只在**部分安卓浏览器**上可能有值。两台同型号设备靠自动标签是分不出来的;
- **手动改名**:每条有「改名」入口(**录入员及以上**可用,与切页同档)——点它就地出现一个输入框(示例 `二号楼平板`),填好按「保存」(`Enter` 也行);旁边的**「清除」**回到自动标签、**「取消」**什么都不改。名字**存在服务端**,**重启服务端与切换赛事项目都不丢**(输入框下方就写着这句),最长 **40 个字符**;
- 显示优先级是 **手动名 → 自动标签 → 那个随机实例 id**(id 降级成小字,排障时还在);读不出设备名时(老服务端 / 浏览器不报)列表退回显示 id,不会空着。**鼠标停在设备名上**还能看到排障要的那几行:设备标签、**原始 UA**、实例 id、来源 IP、屏号(取不到的整行不出现);
- **上限 200 条**:满了会**拒绝新增并提示先清理**(不会悄悄顶掉别的设备);
- 别名跟着**设备**走:设备太久没连、条目被服务端清理之后,**别名仍然留着**,同一台设备再连上来还是那个名字。
> **以前给局域网设备切页后列表会多出一条离线条目**(根因是翻页会补发一次握手,而浏览器没有稳定 id、服务端每次都新开一条实例):现在已经修好——**浏览器本机记住自己的实例 id**,服务端也做了兜底(同一条连接重复握手复用原实例),**不会再出现这种重复条目**。
**逐屏 / 逐设备切页**:在线大屏列表里每一行都在「当前页」旁带一个页面下拉和「切到此页」按钮,只把**这一块屏 / 这一台设备**切过去,其他屏不受影响;上方「切页」卡片里的「立即跳转」则是**所有大屏一起切**。离线实例的下拉与按钮是灰的,发不到它;点名的大屏一台都没收到指令时会明确提示「目标大屏已离线,请刷新在线列表」,不会谎报成功。列表读取失败时页面会提示「读取在线大屏失败」,并保留上一次的结果,不会把列表清空。
**局域网大屏**:这张卡片是给「用别的设备当大屏」准备的——把主机在局域网里可用的地址拼成完整链接,手机 / 平板 / 电视浏览器打开就是一块只读大屏(卡片上就写着「在别的设备浏览器打开下面的地址,就是一块大屏。」)。
- 卡片右上角徽标显示「N 个可用地址」;每个地址一行,**点链接**直接在新标签页打开,点旁边的**复制**按钮把完整地址(形如 `http://192.168.1.5:19540/display`)复制到剪贴板,按钮会短暂变成「已复制」;
- **第一个地址带一个常驻二维码**(下方注明「手机扫码直接打开」),手机相机一扫即可打开,省去手敲长地址;**其余每条地址右侧多一个「二维码」按钮**:**点一下临时显示**那条地址的码,**再点一次 / 按 Esc / 点空白处**都能收起,**同一时刻只留一个**(屏幕小的时候不必为别的网段留一块地方);
- **地址分三类**,卡片会照实把可用地址都列出来(排除的只有回环、未指定、组播、广播这四类对本机之外没有意义的地址):
- **内网地址**(`192.168.x.x`、`10.x.x.x`、`172.16–31.x.x` 这类):路由器 / 交换机分配或手工设好的地址,也是最常见的现场用法,**排在最前**;
- **全局地址**:不在上面这些网段里的地址(运营商专线等),能用就照常列出来,只是**排在私网地址之后**;
- **自动配置地址**(`169.254` 开头):说明**本网段没有 DHCP**、地址是设备自己配的——在**独立小网络**(没有路由器、设备直连或只接一台交换机)里这是**正常用法**,同网段设备可以互相访问。这类地址**排在最后**,旁边有一句「自动配置地址:本网段没有 DHCP,同网段设备可以互相访问」;
- **两种「不那么确定」的来源会各带一句提示,照常能用**(链接与二维码照给,只是说清这条是怎么来的,打不开时换下一条):
- 网卡状态读不到(驱动或虚拟网卡)时:「网卡状态读不到(可能是驱动或虚拟网卡),地址本身可用,打不开就换下面一条」;
- 按系统默认路由推断出来时:「这条地址是按系统默认路由推断出来的(网卡枚举里没有它),地址本身可用,打不开就换下面一条」;
- **手动添加地址**:自动检测不到、或者列出来的不是你要的那个网段时,用卡片下方的「手动添加地址」(说明「自动检测不到时,把 ipconfig 里的 IPv4 地址填进来」)把 `ipconfig` 里那个地址填进去、点「添加」——**立刻出链接和二维码**。手填的**排在第一条**、带「手动」徽标,右边多一个「删除」可以撤掉;它记在浏览器本地(localStorage),**刷新不丢**,最多记 10 个。填错不会没反应,而是就地红字说明:没填「请先填一个 IP 地址」、带空格「地址里不能有空格,请重新复制一次 ipconfig 里的地址」、不像地址「这不像一个 IP 地址,请填 ipconfig 里的 IPv4 地址」、重复「这个地址已经在列表里了」;
- **空态**:会**列出检查过哪些网卡、各自为什么被跳过**,例如「没找到可用的局域网地址。已检查:以太网(接口未连接)、WLAN(只有 IPv6 地址)。」——原因有「**接口未连接**」「**只有 IPv6 地址**」「**接口没有地址**」「**回环接口**」四种,最多列 5 条,网卡更多时其余折叠成「**等共 N 块网卡**」。老版本服务端不返回这份清单时,显示的仍是「未检测到局域网地址(可能是没插网线 / 只有回环)。」;如果显示的是「服务端没有下发大屏端口,暂时拼不出能在别的设备打开的地址。」,那是服务端异常,重启 Console / 服务端后再看;
- 卡片底部注明「地址由服务端下发的端口与路径拼成;平板上打开后不必登录,大屏本身是只读的」——**平板 / 电视那边不用登录**,只有看这张卡片(也就是本管理面板)才需要身份;
- **权限**:这张卡片需要**录入员(recorder)及以上**登录才看得到,只读访客(guest)看到的是「只有登录后的录入员 / 管理员能查看局域网地址,当前为只读访客。」;账号权限不足时提示「当前账号没有查看权限,请先登录(该接口需要录入员及以上)。」;
- 复制失败(浏览器不允许自动复制)时会提示「复制失败 / 浏览器不允许自动复制,请手动选中地址复制」,手动选中地址复制即可。
### 9.1 显示器菜单(重建被关掉的大屏窗口)
扩展屏上的大屏窗口平时由服务管理程序(Console)按配置自动开出来,只有在**有人手动关掉了某块屏的大屏窗口**时才需要这一节。
这张「显示器」卡片只在**从服务管理窗口点「打开服务端管理面板」打开的面板**里可用;用浏览器直接打开管理面板时,卡片只显示一行提示,这是正常的。
1. **窗口页面**:先选好新窗口锁定显示哪一页(默认「总积分榜」);
2. **显示器列表**:逐块屏列出名称、分辨率、缩放、是否主显示器、当前是否已开窗口(「已开窗口(全屏)」「已开窗口(窗口化)」或「未开窗口」),以及**该屏窗口当前在哪一页**(没开窗口时显示「窗口未开」;窗口开着但还没上报时显示「未上报」);
3. **每行的按钮**:
- 该屏的窗口已连上服务端(列表里能找到对应的在线实例)→ 页面下拉 + **切到此页**:只把这一块屏切过去,不影响别的屏;找不到对应在线实例时这两个控件是灰的,行内会注明原因(「该屏窗口已关闭(实例离线),先开窗或等它重连」或「该屏窗口未开,或大屏没上报屏号」);
- 该屏已经有窗口 → **聚焦窗口**:把窗口提到最前,不重建、不打断正在展示的比分;
- 该屏还没有窗口,且允许多屏全屏 → **创建全屏窗口**;
- 该屏还没有窗口,但不允许全屏 → **创建窗口(窗口化)**,行内会注明「单显示器 / 主显示器只能窗口化」;
- 已开窗口的行还有一个 **关闭窗口**:全屏大屏窗口画面上没有任何可操作的按钮(也不响应键盘),万一开到了错误的屏上,从大屏本身退不出来,用这个按钮收掉;
4. **重新排布(按设置重建全部窗口)**:按服务管理程序里的选屏配置重建所有大屏窗口。不在该配置范围内的窗口会被关掉,所以日常只想恢复某一块屏时,请优先用上面的「创建」按钮。
**为什么单显示器 / 主显示器只能创建窗口化窗口**:全屏窗口会盖住整块屏,而且没有标题栏和关闭按钮。单显示器上开全屏,等于把操作人员的桌面整个盖住;主显示器上开全屏,会把服务管理窗口、管理面板这些工作窗口全部遮住——现场又没有键盘可以退出来。所以这两种情况下按钮只提供窗口化:窗口约占屏幕 80%、居中显示、带标题栏,随时可关。只有「本机有多于一块显示器,且目标不是主显示器」时才放行全屏。
**副屏全屏窗口被误关后,一键恢复**:
1. 在服务管理窗口点「打开服务端管理面板」;
2. 进入管理端「大屏控制」页;
3. 在「显示器」卡片里找到那块副屏(那一行没有「主显示器」标记,且分辨率/缩放与副屏一致),点它的 **创建全屏窗口**;
4. 列表刷新后该行显示「已开窗口(全屏)」,副屏上即出现全屏积分榜。
多块副屏都被关掉时,在同一张卡片里逐块点「创建全屏窗口」即可;改用「重新排布」也行,但前提是这些屏都在 Console 的选屏配置里。
### 9.2 赛事日程(手填日程 + 大屏上的侧边栏)
**这张卡片是干什么的**:把**手填的赛事日程**做成大屏上一块**侧边栏**,里面是一条**竖向进度轴**。它**与大屏当前在哪一页无关**(轮播中、锁在某一页都照常显示),也**不影响**切页与轮播。**录入员及以上**可改(与大屏公告、逐屏切页同档);未登录 / 服务端未连接时整张卡片禁用并写明原因;示例数据模式下会提示改动未真正保存。
**位置**:本页**左列、公告卡之后、「实时赛况」之前**;卡头徽标写 `N 条 · 默认开启 / 关闭`。
**表格怎么填**:
| 列 | 怎么填 |
| --- | --- |
| 时间 | **自由文本**,最长 **20** 字(`08:30`、`上午`、`待定` 都行)。⚠️ **必须填**(不能留空),否则保存时服务端会退回一句「第 N 条日程的时间不能为空」 |
| 标题 | **必填**,最长 **40** 字 |
| 备注 | 可留空,最长 **60** 字(例如 `检录 08:00`);**默认上屏**,可用下面的「备注上屏」整体关掉 |
| 已完成 | 勾上 = 这条已完成(大屏上会**淡化保留**) |
| 操作 | **上移 / 下移 / 删除**——**只有这三个按钮,不能拖拽排序**;第一行的「上移」、最后一行的「下移」是灰的 |
- 表格下方是「**新增一条**」按钮,右侧写 `共 N / 40 条`(**最多 40 条**,满了按钮不可点);一条都没有时显示「还没有日程条目」;
- **上屏顺序就是你排的顺序**:系统**不解析时间、不比较、也不按时间自动排序**(手填文本没法可靠解析);
- **校验不过时一个请求都不发**:字段级红字贴在该格下方,条数 / 宽度这类整表错误列在表格下方,同时提示「赛事日程校验未通过 / 请先修正标红的字段」。
**开关与几何**:
- **侧边栏默认开启**:总开关。开 = 所有大屏默认显示(除非那块屏被单独设成「强制关」);关 = 所有大屏都不显示;
- **备注上屏**:关掉后大屏上只显示时间与标题;
- **位置**:左侧 / 右侧(默认**右侧**);**宽度**:占整屏的百分比,**15–40 %**(默认 **22 %**)。
**每块屏单独设置**(覆盖上面的总开关):卡片下半部分**一行一块屏**,显示名按 **手动别名 → 自动设备标签 → 实例 id**(怎么改名见本节前面「在线大屏」那段),右边一个三态下拉:
| 选项 | 含义 |
| --- | --- |
| 跟随总开关(默认) | 由上面的总开关决定 |
| 强制开 | 这块屏**无论总开关怎么设都显示** |
| 强制关 | 这块屏**不显示** |
- 切回「**跟随总开关**」会**真的把那条覆盖删掉**(不会留一个没用的空键);
- 列表里**列全部在线实例**,另外把「离线、但身上挂着强制开 / 强制关」的也列出来(否则那块平板今天没开,你就再也撤不掉它的强制关了);**还没有任何大屏上报**时这里显示「还没有大屏上报,暂时没有可单独设置的设备;新设备接上后回到这里即可」;列表里已经找不到的覆盖条数会另写一句说明——那些设置**照原样保存**,不会被悄悄删掉。
**保存**:点「保存」= **整份替换**并**立刻推给所有大屏**(这就是「热开关」:不用刷新、不用重启)。成功提示形如「已把赛事日程改成「共 2 条 · 默认开启 · 右侧 22%」」,并注明「大屏立刻生效;配置随赛事库保存,刷新与重启都不会丢」;失败会把**服务端原文**显示出来(条数超限 / 字段过长 / 权限不足)。
⚠️ **这是低频动作**:每次保存都会让**全场大屏做一次全量重拉**(局域网内几百毫秒,现场基本无感)——所以它适合「**开赛前配一次 + 现场偶尔勾一下「已完成」**」,**不要**拿它做高频刷新。
**配置存在哪**:赛事库的设置里(键名 `display.schedule`,与大屏公告同一套机制)——**不新建表、不改数据库结构**,**随赛事包一起导出 / 导入**;刷新、重启服务端、切换赛事项目都不会丢。
---
## 10. 基础数据
页面分七个分区,从左到右依次是:参赛单位、大项 / 小项、组别、计分通道、积分模板、运动员、报名导入。
### 10.1 参赛单位
1. 点「新增单位」;
2. 填写代码 *(唯一,字母 / 数字 / `_` / `-`,最长 16 位)、全称 *、简称、主题色、排序、logo(可点输入框右侧「上传图片」直接传,png / jpg / webp / gif,单张不超过 5 MiB;也能手填已有路径,留空则不显示);
3. 每行有三个动作:**编辑**、**停用**(已停用的单位显示为「启用」)、**彻底删除**。
**停用与彻底删除的区别**
| 状态 | 单位列表里 | 还能被报名选中吗 | 它的报名 / 成绩 / 积分 | 能恢复吗 |
| --- | --- | --- | --- | --- |
| 启用(默认) | 在 | 能 | 保留 | —— |
| 停用 | 还在(标「已停用」) | 仍可手动选(「全选」不会自动带上它) | **保留** | 点「启用」即可 |
| 彻底删除 | **默认不在列表里**(管理员勾选「显示已彻底删除的单位」后可见,标「已删除」) | 不能 | **保留** | **管理员可在列表里点「恢复」**;再次导入用到它的编码也会自动回来 |
「停用」还是软删除:单位留在列表里,历史成绩与积分流水保留,随时能再「启用」。「彻底删除」是**假删除**——只把这个单位从参赛单位列表里移除,它的报名、成绩、积分流水、人工调整、纪录与名下的运动员**一条都没删**,**积分榜也不会变化**,不会触发任何重算。操作步骤:
1. 点该行右侧红色的「彻底删除」;
2. 在确认框里核对提示(会写明该单位从列表与报名选择里移除、已有报名与积分不受影响、积分榜不变,以及恢复要找谁),再点一次「彻底删除」;
3. 完成后该单位从默认列表里消失,页面提示「已彻底删除「XX」」。
**怎么恢复**:只有**管理员**能在参赛单位页勾选「**显示已彻底删除的单位**」把它们翻出来,点该行的「**恢复**」即可。恢复是幂等的——它本来就还在时会提示「本就未被彻底删除」;如果这个编码已经被另一个可见单位占用(只能来自手工改库),会拒绝并说明原因。**录入员(recorder)界面上看不到这个开关**,删错了要**找管理员恢复**(删除确认框里也写了这句)。
**「彻底删除」之后会发生什么**
- 该单位**不再出现在默认的参赛单位列表**里,报名选择(含团体报名、运动员的「所属单位」下拉)里也选不到;
- 它的**报名、成绩、积分流水、人工调整、纪录与名下运动员全部保留**——消失的只是这个单位本身;
- **积分榜照旧显示它**:单位本来有分数的话,总积分榜、单位奖牌榜上仍有它的名字与分数。这是刻意设计(数据没删,分数就不该凭空消失),不是故障;
- **再次导入报名表时,如果用到这个单位的编码,它会自动复活**并重新出现在列表里——这里和人员不同:删掉的人再次导入是**以新档案建档**(旧数据回不来),删掉的单位则是**原来那条记录直接恢复**,报名、成绩与积分一直都在(见 10.7);
- 单位名下还有运动员时同样可以删,这些运动员不会被一起删掉,但他们编辑起来会有些不便(见常见问题 Q64)。
> ⚠️ **别和运动员的「彻底删除」混为一谈**:两个页面上的按钮同名,行为完全不同。运动员的「彻底删除」是**真删除**——人员档案连同他名下的报名、成绩与积分流水一起从库里删掉,并重算受影响小项的排名与积分(见 10.6);参赛单位的「彻底删除」是**假删除**——业务数据一条不删,只让单位从列表里消失,积分榜不变。
> 上传的 logo 会显示在**大屏**的总积分榜、单位奖牌榜、分项成绩与个人积分奖牌榜上(个人积分奖牌榜显示在运动员姓名前面);没传 logo 的单位不占位,队名不会因此错位。管理端页面不显示 logo。
### 10.2 大项 / 小项
1. 左侧选择或新增大项(编码、名称、简称、默认积分模板、排序);
2. 右侧维护该大项下的小项:点「新增小项」,填写编码、名称、类型(个人 / 团体 / 对抗 / 比赛 / 个人+团体)、录入方式(自动排名 / 手动名次)、成绩类型(时间 / 距离 / 计数 / 得分 / 无成绩)、比较方式(越小越好 / 越大越好 / 不比较)、状态、是否计分、**是否结算奖牌**等;
- **小项名里不能用 `@`**:它是「分工作表报名模板」里工作表名「小项名称@组别名称」的分隔符(见 10.7),填了会当场标红说明;已经带 `@` 的历史名字不影响任何报名、成绩与积分,只会在下载分工作表模板时被点名,改名即可;
3. 小项行上的「配置组别」「配置计分通道」可直接跳到对应分区;
4. 删除大项 / 小项会二次确认。
**「该项启用奖牌结算」开关**(新增)
小项表单下方的「选项」里,"是否计分"旁边有一个 **「该项启用奖牌结算」** 勾选框,**默认勾上**。
- **勾上(默认)**:这个小项按名次发奖牌——第 1 名金、第 2 名银、第 3 名铜,和以前一样;
- **取消勾选**:这个小项的**名次与积分照常计算、照常上屏**,但**一块奖牌都不发**——金牌榜(单位奖牌榜)与个人积分榜的奖牌列里都不再出现它。
什么时候该关掉它?**"算分但不发牌"的项目**——例如赛会规则只记名次分、不设金银铜的项目,或者现场临时决定不发牌、但分数仍要计入单位总分的项目。
> 注意别和「计分」搞混:**取消勾选「计分」**的项目(只排名不计分)本来就不发奖牌,那种情况不用动这里;**「该项启用奖牌结算」管的是"计分的项目里哪些要发牌"**。
>
> 它保存后立即生效:系统会马上重算该小项,金牌榜随之更新。想恢复发牌,把勾重新勾上保存即可。
> 这是"小项级"的总闸;某个小项里**单独某条计分通道**不发牌,另有开关,见 10.4。
**「个人+团体」是什么**
用于团体与个人赛事合并的项目:同一条成绩会同时按个人通道与团体通道记分(具体通道见 10.4「计分通道」)。
- 个人通道按个人成绩排名给分,分**只记在个人积分榜**,不计入单位总分;
- 团体通道把本单位成员在该组别的成绩**取平均**后排名,按团体模板给分,这部分才进单位总分;
- 平均值的分母(「平均值口径」)在**成绩录入页**选,见 4.1:`只算有效成绩`时,一个人都没成绩的单位不参与团体排名、不得分;`全部报名人员都计入`时,没成绩的按 0 计入,分母是本单位在该组别的报名条数(一人一条报名时就是报名人数)。
**配一个「个人+团体」小项的完整链路**
1. 在「大项 / 小项」新建小项,类型选「个人+团体」,保存;
2. 到「组别」分区配置组别(团体平均是按组别算的,参赛的组别都要有);
3. 到「计分通道」分区配上两条通道并「保存全部」——新建小项不会自动生成通道:
- 个人通道:名次范围 `个人名次`、名次来源 `按成绩自动排名`、选个人积分模板、**「计入单位总分」取消勾选**;
- 团体通道:名次范围 `团体名次`、名次来源 `按队内平均`、选团体积分模板、「计入单位总分」保持勾选;
- (导入规则包时,规则包里的 `channelTemplates` 会按项目类型自动生成这两条通道,见 11.3。)
4. 到「报名导入」把参赛人员报上:切到「个人报名」一人报一条(团体平均取的就是这些人的成绩)——注意「个人+团体」类型默认停在「团体报名」页签,要手动切过去;只想让某个单位参加团体、暂不登记具体人员时,也可以用「团体报名」只报单位;
5. 到「成绩录入」逐人录成绩,顺便在「平均值口径」里选好分母口径;发布后个人榜与单位总分同时更新。
> 「个人+团体」项目的个人通道要有成绩才给分,所以参赛人员必须按人报名(团体报名只报单位不会产生个人成绩)。
### 10.3 组别
1. 先在上方选中一个小项;
2. 点「新增组别」,填写名称、权重、性别、年龄上下限、排序;
- **组别名里不能用 `@`**(小项名同):它是「分工作表报名模板」里工作表名「小项名称@组别名称」的分隔符(见 10.7),填了会当场标红说明。已经带 `@` 的历史名字不影响任何报名、成绩与积分,只会在下载分工作表模板时被点名,改名即可;
3. 用「上移 / 下移」调整顺序,「移除」删除;
4. 点「保存」提交。**已有报名数据的小项**:改名 / 改年龄 / 改性别 / 改权重 / 改排序会**就地保存**——组别本身不重建,挂在它下面的报名、成绩与积分流水一条不动;其中**改权重会立即按新权重重算该项目已发布成绩的积分与榜单**,改名 / 改年龄 / 改性别 / 改排序不会。**新增或删除组别**仍走「整体替换」,有报名数据时服务端会拒绝(组别一重建,挂在它下面的报名就断链了)——要增删请先撤掉增删操作、只保存字段修改。
> **组别之下还有「批次」**:批次(`第 1 批`、`第 2 批`…)是在**成绩录入页**给报名行分的录入 / 展示分组,不属于这里的组别配置,也**不参与算分**——名次与积分仍按「小项 + 组别」整体计算。怎么分批见 4.1。
### 10.4 计分通道
通道 = 「排谁的名次 + 名次从哪来 + 用哪张积分模板」。
1. 先选中一个小项;
2. 点「新增通道」逐条配置,同一「名次范围 + 名次来源」只能有一个通道;
3. 点「保存全部」整体替换该小项的通道配置;
4. 标记为「不计分」的小项,通道可以保存但不参与积分计算;
5. 「名次来源」选「按队内平均」时,把同一个单位(或个人)在该组别的成绩**汇总成一个值**后排名,并列按积分模板的并列口径处理(默认顺延)。汇总口径在该行的**「聚合口径」列**上选,三个按钮点一下即切换:
- **平均**(默认):团体成绩 = 该单位成员成绩的**平均值**。分母取录入页选的「平均值口径」——`只算有效成绩`时是本单位有有效成绩的条数(一个人都没有效成绩的单位不参与团体排名、不得分),`全部报名人员都计入`时是本单位在该组别的报名条数(没成绩的按 0 计入);
- **总和**:团体成绩 = 该单位成员成绩的**总和**(没成绩的人按 0 加与不加都一样)。
- **队内最低分**:团体成绩 = 该单位成员里**最差的那一份**成绩——**取的是谁,由小项的「比较方式」决定**:
- 比较方式 = **升序**(时间这类**越小越好**的项目,例如越野 / 行军):取**跑得最慢的那个人**,也就是**最后一名冲线**的那个人的成绩;
- 比较方式 = **降序**(次数这类**越大越好**的项目,例如引体向上):取**做得最少的那个**。
现场用途:赛会规则写「取团队最后一人的成绩」的项目就是它。⚠️ **别按字面理解成"取最小的那个"**——时间项目里"最小"是最快的人,正好是反的;
- **各队人数相同时,平均与总和排出来的名次完全相同**;人数不同时可能不同(这时按你们要的口径选,默认是「平均」)。「队内最低分」与它们都可能不同(它只看队里最差的那一份,与人数无关)。改完点「保存全部」生效,该小项立即重算;
- 报名表里 `status` 不是 `registered` 的报名项(弃赛 / 取消)既不算参与,也不进分母;**「队内最低分」下弃赛的人的成绩也不代表队伍**(弃赛那一格填得再差也不算),队伍成绩只在实际出赛的人里取;
- **「队内最低分」下,一个有效成绩都没有的单位不参与团体排名、也不得分**(没人冲线就没有"最后一名冲线"可言;这一条与「平均值口径」选哪个无关);
- 不是「按队内平均」的通道这一列显示 `—`(对它没有意义);
6. 每条通道有一个「计入单位总分」开关。**新建通道时的默认值按小项类型给**:**普通个人项目 / 团体项目默认勾选**;**「个人 + 团体」项目的个人通道默认不勾**(这类项目的个人分本来就只记个人榜、不并入单位总分)。关掉后该通道的分只记在个人头上,不进单位总分——「个人+团体」项目的个人通道就靠它做到只记个人;**所以现场要留意自己那一行的实际勾选状态**;
7. 每条通道还有一个**「奖牌通道」**列,里面是两个开关(都默认打开):
| 开关 | 默认 | 关掉之后 |
| --- | --- | --- |
| **发奖牌** | 打开(该通道的名次发奖牌) | 这条通道算出来的名次**只出积分、不发奖牌**:名次与分数照旧,金牌榜与个人榜里不再为它记牌 |
| **个人奖牌并入单位金牌榜** | 打开 | 只对「名次范围 = 个人名次」的行显示。关掉后这条通道的个人奖牌**仍然进个人积分榜的奖牌列**,但**不计入单位的金牌榜**(单位奖牌榜 / 单位总分榜的金银铜) |
怎么用:
- **什么该关「发奖牌」**:一条通道只用来给分、名次不该算奖牌时——例如个人通道的分要记、但这批名次不是赛会正式名次;
- **什么该关「个人奖牌并入单位金牌榜」**:某个个人项目**不按单位计牌**时(单位金牌榜只统计团体项目的牌子、或该项目被判定为个人项目不计入单位成绩);
- 「名次范围 = 团体名次」的行**不显示**第二个开关:团体名次本来就是记在单位头上的,不存在「个人奖牌并入单位」这回事;
- 两个开关**都在「保存全部」之后生效**,保存后系统会重算该小项并更新榜单;
- 这些开关只决定**发不发牌、算不算单位榜**,**不改变积分**(积分由「计入单位总分」与积分模板决定,见第 6 条)。
> 三个层次一起决定一枚奖牌:**小项的「该项启用奖牌结算」(见 10.2)→ 通道的「发奖牌」→ 名次在前三**。三者都满足才有奖牌;「计入单位金牌榜」再决定这枚牌算不算到单位头上。
> 想知道某个小项到底发不发牌:在「大项 / 小项」页选中它,页面下方「当前小项的计分通道」摘要里,关掉的开关会直接标出 **`不发奖牌`** 与 **`个人奖牌不并入单位榜`**。
### 10.5 积分模板
1. 左侧点「新建」创建模板,填写编码、名称、并列处理、破纪录加分、录取名次、末位归零;
2. 在「名次 → 分值」表格里添加 / 移除分值明细;
3. 保存会整体替换该模板的分值明细,请核对后再保存;
4. 页面下方的「榜单口径(全局)」卡片设置**个人项目得分折算系数**(默认 1,步进 0.1,必须大于 0 且不超过 100):`单位总分 = Σ 只记单位的流水 + 系数 × Σ 记到个人的流水`。它是**全局**设置(键名 `standings.individual_to_team_weight`,不随某一张模板保存,所有模板与所有计分通道共用;导入规则包时,规则包里的同名配置会覆盖它),只有管理员能改,点「保存榜单口径」后榜单按新系数立即变化。「个人+团体」项目的个人通道已经用「计入单位总分」关掉了折算,这里的系数对它没有影响。
**同一张卡片里的「分批发布时实时更新榜单」开关(默认开)**
- **开(默认)**:每发布一批成绩就立即重算名次、各单位总分与奖牌榜,即 4.6 描述的行为;
- **关** = **延迟结算**:分批发布时**只把成绩上屏,不动积分与名次**;等**该项目该组所有批次都录完**(报名状态不是「正常参赛」的人——退赛 / 取消资格 / 未出场——不算在等待里)才一次性结算,更新榜单与奖牌。未结算的组在分项成绩 / 最新成绩里的**名次显示 `—`**(成绩照常显示)——这是有意的,否则会出现「有金牌但 0 分」的自相矛盾;
- 有人永远录不出成绩时,到**成绩录入页**点 **「立即结算」** 兜底:按当前已发布成绩先结算一次,补录完还会再自动结算;
- 勾选 / 取消后点「保存结算方式」生效;只有管理员能改。
### 10.6 运动员
1. 点「新增运动员」,填写姓名 *、性别、年龄、所属单位 *、工号 / 学号、证件号、号码布等(年龄可留空,填了必须是 0–120 的整数);
2. **证件号(如身份证号)是单人的唯一标识**,同名同姓的人靠它区分,两个人的证件号不能重复;**没有身份证信息的人只填号码布**,此时号码布顶替证件号认人(报名导入会先按证件号认人,没有证件号或库里那条证件号为空时再按号码布认人),两个人的号码布同样不能重复。两项都不填也能保存档案,但这样的人员**不能在「报名导入 → 个人报名」里勾选**(系统认不出是谁)。已有历史数据两项可以都为空;
3. 每行有三个动作:**编辑**、**停用**(停用后按钮变成「启用」)、**彻底删除**;
4. 个人项目的报名项会关联到运动员,团体项目可以留空;
5. **多选与批量操作**:列表每行有勾选框,表头是「全选当前筛选结果」(只勾当前筛出来的人)。选中后顶部出现「已选 N 人」与 **批量停用** / **批量彻底删除** 两个按钮,整批只提交一个请求,不用一个个点;**批量彻底删除**会先预览将删掉谁、重算哪些小项,确认后才执行,规则与单个「彻底删除」完全一致(见下)。
**停用与彻底删除的区别**
| 状态 | 人员列表里 | 还能被报名选中吗 | 他名下的报名 / 成绩 / 积分 | 能恢复吗 |
| --- | --- | --- | --- | --- |
| 启用(默认) | 在 | 能 | 保留 | —— |
| 停用 | 还在(标记「已停用」) | 不能 | **保留** | 点「启用」即可 |
| 彻底删除 | **不在了** | 不能 | **一并删除** | 恢复不了 |
「停用」是软删除,只是不让他再报名;「彻底删除」是**真删除**。操作步骤:
1. 点该行右侧红色的「彻底删除」;
2. 在确认框里核对提示(会写明报名与成绩一并删除、相关小项的排名与积分会重算),再点一次「彻底删除」;
3. 完成后页面给出删除规模,例如「已彻底删除「张伟」:报名 1 条、成绩 1 条、积分流水 2 条,已重算 1 个小项的积分与名次」。
**「彻底删除」会永久删掉什么**
- 这个人的**人员档案**:从运动员名册里消失,报名选择器里也选不到,界面上再也恢复不了;
- 他名下的**报名**与**成绩**;
- 这些成绩产生的**积分流水**(含已作废的历史流水)与**破纪录记录**。
删掉成绩会改变同组其他人的名次与得分,所以系统在同一个动作里**按新排序重算受影响小项的排名与积分**,并把结果推到大屏。因此:
- 已经有成绩的比赛,删人**会让名次和积分发生变化**(例如原来的第二名升到第一、得分跟着变),删完请核对一下榜单;
- **只是想暂时不让他报名**,请用「停用」——它保留全部历史数据,随时可以再启用;
- 该人的姓名也不会再出现在「分项成绩表」「个人积分榜」上:这些榜单是现算的,数据删了他就不在榜里。
### 10.7 报名导入
报名有两种方式,都在本页完成:**从已有名单勾选**适合零散补报,**表格导入**适合批量录入。
> 两个单位因参赛人数不足**合并成一个队参赛**时,不要建一个「联队单位」——**在导入表的「单位编码」列写 `F1+F2`**,或导入后到「成绩录入」页点那一行的「单位」格配成员单位与份额(见 4.11)。榜单仍是原来的单位数,分数与奖牌按份额记给各单位。
> 本页的「从已有名单勾选」在**成绩录入页的工具栏里也有一个入口**(按钮叫 **「补报名」**),打开的是同一套勾选界面,只是预选了你正在录的那个小项与组别——在录入界面把某人移出报名之后,就地补回来即可(见 4.8)。
**从已有名单勾选**
这张卡片分成「个人报名 / 团体报名」两个页签,页签下方的小项与组别选择是两个页签共用的。选中某个小项后会自动切到与该小项类型相符的页签(个人项目 → 个人报名;团体 / 对抗 / 个人+团体 → 团体报名),也可以手动切换;切到的页签与小项类型不符时页面会提示一句,生成的报名以当前页签为准。
**个人报名**(一人一条报名)
1. 选择单位,按姓名 / 工号搜索并在运动员列表里勾选:已报名的运动员显示「已报名」且不可重复勾选;证件号与号码布都没有的运动员显示「缺证件号/号码布」、不能勾选,请先到「运动员」分区补齐其中一项;
2. 点「加入报名」,结果同样显示**新增 / 更新 / 跳过**数量;报名会自动带上该运动员的证件号与号码布。
**团体报名**(默认一个单位一条报名;同一个单位要派两支队时见 4.12)
1. 在参赛单位清单里勾选要参加本组别的单位,**默认一个都不勾**——不参加的单位不勾即可;每行显示该单位是否「已报名」、已登记几名队员;
2. **同一个单位要派两支队时**(羽毛球双打那种):勾上这个单位后,那一行右侧会出现 **「队伍(留空=不区分)」** 输入框,填上队名(例如 `一队`);**没勾的单位不显示这个框**。已经报过的单位徽标会写成 `已报名(一队、二队)`——**要再报第二支队,就再填一个新的队名提交一次**(同一个队名重复提交只是更新队员名单,不会新增)。详见 4.12;
3. 要登记队员时点该行的「登记队员」展开名单逐个勾选(可按姓名 / 工号搜索);一个队员都不勾就是**纯单位报名**,队员名单之后还能再补。
- **这里勾上的队员会真正提交到报名上**(不是只存一串姓名):配了「个人通道」的项目里,他们会各拿一份个人分、各一枚个人奖牌,也上得了个人积分榜——详见 **4.13**;
4. 勾选「已报名」的单位会出现「提交将清空原名单」提醒:再次提交是用本次登记的队员覆盖原名单;
5. 点「加入报名」,一次为所有勾选的单位各建一条报名(**同一个单位 + 同一个队名**只留一条)。
- 「全选」只勾启用中且还没报名的单位(已停用的单位要单独勾),且不会展开队员面板;「清空」只取消单位勾选,已登记的队员名单留着,重新勾上就回来。
> **用表格导入报团体时注意「姓名」列**:报名表里的**「姓名」列填了就是个人报名**——这一格是系统区分个人 / 团体报名的**唯一判据**。想报一支队却把队里某个人的姓名填进这一列,导入后会落成**他的个人报名**,那一行的「队伍」与「队员名单」都不生效(导入结果里会给出可照改的中文提示)。**团体报名请把「姓名」列留空,队员的号码布写进「队员名单」列**(写号码布才会关联到人;只写姓名只当文字名单)。两种填法的逐列对照见[报名名单导入规范](./报名名单导入规范.md)。
**表格导入**
> 报名表的完整格式、每一列怎么填、个人 / 团体 / 「个人+团体」三种项目的填法和常见报错对照,见单独一份文档 [报名名单导入规范](./报名名单导入规范.md)——**可以直接把那份文件发给各单位填表人**。
1. 点「下载模板」拿表头样例。四个按钮对应两种模板,**两种都能导入**:
- 「**中文表头 / 英文表头**」=**单表模板**(`entries-template-zh.csv` / `entries-template-en.csv`):一份表装全部报名,每行都要填「项目编码」与「组别」两列;
- 「**分工作表 · 中文表头 / 分工作表 · 英文表头**」=**分工作表模板**(`.xlsx`):按当前赛事已配好的**小项 × 组别各建一张工作表**,表名是「**小项名称@组别名称**」(例如 `100 米跑@男子组 30岁以下`),范围由表名承担,数据区只填人和单位。小项组别多时用它更不容易抄串;
- 两种模板的表头与列顺序完全一样,只有「范围从哪来」不同(详细规范见 [报名名单导入规范 · 第八节](./报名名单导入规范.md));
- **两个单位联合参赛(联队)**:把「单位编码」那一格写成 `F1+F2`(加号左边是主单位,默认均分,见 4.11)。**分工作表模板**里,「单位编码」表头那一格挂了一条**单元格批注**(鼠标停上去就弹出来)、这一列还有**输入提示**(点中该列的格子就弹出来),中英各一份,写的正是这套写法——表头文字、列顺序与工作表名一个字都没动,**老表格照常导入**;
2. 表头共 13 列:`event_code`、`category`、`team_code`、`athlete_name`、`id_card`、`gender`、`age`、`bib`、`seed`、`heat`、`status`、`member_names`、`squad`(大小写不敏感)。其中 `id_card`(证件号)、`gender`(性别)、`age`(年龄)、`heat`(批次)、`squad`(队伍)为可选列,缺失不影响导入,其余列必须包含;
- `team_code`(单位编码)有两种填法:**一个单位**填它的编码(`F1`);**两个单位联合参赛**填 `F1+F2`(加号左边是主单位,默认均分;非均分要到录入页改,见 4.11);
- `athlete_name`(运动员姓名)这一格**填了就是个人报名**(这一行属于这个人);**团体报名请留空**,队员的号码布写进 `member_names`(队员名单)列——两格都填的行会按**个人报名**导入,队伍与队员名单不生效(导入结果里会给可照改的中文提示),详见[报名名单导入规范](./报名名单导入规范.md);
- `squad`(队伍)是**最后一列**、**新加的(2026 年 9 月)**:同一个单位在同一个组别派两支队时(羽毛球双打的一队 / 二队)用它区分,写队名即可(中文表头里叫「队伍」,也认「队名」「队伍名」);**只有一支队的单位整列留空**、整列不写、表头里没有它,三种都合法。**老 12 列表照常导入**(新列加在最后,一列都不会错位),详见 4.12 与[报名名单导入规范 · 第三节「队伍」](./报名名单导入规范.md);
- 用**分工作表模板**时,`event_code`、`category` 两列也可以整列不要或整列留空(范围由工作表名决定);一旦填了就必须与工作表名一致,不一致的那一行会报错并跳过;
- 工作表名必须是「小项名称@组别名称」;工作簿里只要有**一张**表名带 `@`,整份文件就按分工作表模板处理,别的表名不合规会**整份拒绝并点名是哪张表**(不让数据无声消失);
- 小项名与组别名里**不允许出现 `@`**(它是表名里的分隔符):新建 / 编辑小项与组别时界面会当场拦下并说明原因;**已经带 `@` 的历史名字不影响报名与成绩**,但下载分工作表模板时会被点名要求先改名;
- 表名超过 Excel 的 31 字符上限、或两个组合截断后撞名时,系统会确定性地截断(保留开头)并自动加 `(2)`/`(3)` 后缀——**下载下来的表名就是最终名字,不要手工改**;
3. **只要有姓名的行,`id_card` 与 `bib` 必须至少填一个**,否则该行报错并跳过;`gender` 只认「男」「女」,其他值忽略;`age` 可留空,填了必须是 0–120 的整数;**证件号是系统认人的第一依据**,同一个证件号在同一份文件里重复出现**不报错**(同一个人报多个组别时会重复,导入结果里会给一条「证件号 XXXX 在本表中出现 N 次(同一人报名多个组别)」提示);同一小项同一个组别里出现两次同样的证件号才按**真重复**进冲突列表;**同一个号码布给了两个不同的人会报错并跳过**(同一个人报多个组别时号码布可以重复);
4. 人员匹配顺序(**证件号是单人的唯一标识**):
1. 先按 `id_card`(证件号)匹配:命中即认作同一人;姓名 / 性别 / 年龄 / 单位 / 号码布与他的档案对不上时进「冲突」列表,等你逐条决定(见下);
2. 证件号为空、或库里那条还没登记证件号,再按 `bib`(号码布)匹配:命中即认作同一人,差异同样进「冲突」列表;
3. 证件号与号码布都没找到,再按「姓名 + 单位」找:
- 恰好一人,两边给的证件号(或号码布)对得上或有一边没填 → 认作同一人,表里给的证件号 / 号码布 / 年龄会**回填**进他的档案(不算冲突),重传不带证件号的名单不会把每个人复制一份;
- 恰好一人,但他已有**另一个**证件号(或号码布)且与表里不同 → 按「**同名的另一个人**」新建档案,并在导入结果里单独列出(姓名 / 单位 / 原证件号或号码布 / 新证件号或号码布)提醒核对,**不算错误、不拦截**;
- 多人 → 分不清是谁,进「冲突」列表;
4. 都没匹配到则新建人员(姓名、性别、年龄、单位、证件号、号码布)——被「彻底删除」的人(见 10.6)档案已经不在库里,匹配不到他,再次导入会当作**新人员**重新建档,他以前的报名与成绩不会回来;
5. **一个证件号只能属于一个人**:表里给的证件号若已是别人的,这一行会按证件号认到**那个人**,姓名 / 单位等对不上就进冲突列表让你决定;确实无法认到(例如同时又给了别人的号码布)时会报「证件号 X 已被另一个人占用(姓名 Y,号码布 Z)」并跳过,不会把证件号抢过来;
5. **`status` 列很宽容**:大小写不敏感(`DNS`、`Registered`、`registered` 都认),也认中文别名——
- `正常` / `正常参赛` / `参赛` → 正常参赛;
- `退赛` / `弃赛` / `请假` → 退赛;
- `取消资格` / `犯规` → 取消资格;
- `未出场` / `未到` / `缺席` → 未出场。
留空即「正常参赛」。真正认不出的写法会给出中文行级错误、该行跳过,例如「第 12 行:status「已报到」无法识别,只能填 registered / scratched / dq / dns(或留空)」;
6. `bib` 列会同时写入人员档案与报名记录;从已有名单勾选生成的报名也会带上人员的证件号与号码布;
7. 把 `.csv` 或 `.xlsx` 拖入虚线框,或点击选择文件(单个文件不超过 32MB);
- **xlsx 怎么读**:只有一张工作表(或表名都不像分工作表模板)时,按单表模板只读**第一张**,其余工作表会在导入结果里提示「没有读」;只要有一张表名带 `@`,整份文件按**分工作表模板**处理,每张工作表各按自己的表名(小项@组别)导入;
- **CSV 编码不用管**:UTF-8、带 BOM 的 UTF-8(Excel 的「CSV UTF-8」)、GBK / GB18030(中文 Windows 上 Excel「另存为 CSV」的默认编码)、UTF-16 都能直接导入,中文不会乱码,服务端会自动识别;
8. 点「开始导入」,页面显示**新增 / 更新 / 跳过**数量;匹配不到的行会跳过并回显行号,修正后可重新上传。
> **导入会同步重算受影响的小项与组别**:报名名单改的是「谁还算数」(新建报名、或把正常参赛改成退赛 / 取消资格 / 未出场),所以导入完成后系统会按新名单重算这些组别的名次与积分,并刷新榜单与大屏——**不受「分批发布时实时更新榜单」这个延迟结算开关影响**(同 4.8 的批量退赛)。「只改了姓名 / 号码布 / 批次」这类不影响算分的改动不会白算一遍。
**人员信息冲突的处理**
导入时如果按证件号(或号码布、「姓名 + 单位」唯一命中)找到的人在系统里已有记录,但表里的姓名、证件号、性别、年龄、单位或号码布与他的档案不一致,这个人会被列为**冲突**,本次不写入(该人的报名也不会创建)。处理办法:
1. 导入结果里会单独列出冲突人员,每条显示已有数据、新数据,以及不一致的字段(含证件号、年龄与号码布);
2. 用左侧复选框选中一条或多条(也可以全选),再点「保留已有数据」或「使用新数据」:
- **保留已有数据**:人员字段沿用系统里已有的,按这个人的信息建 / 更新报名;
- **使用新数据**:用表里的姓名、证件号、性别、年龄、单位、号码布等更新该人员,再建 / 更新报名;
3. **没有做决定的冲突不会被写入**,可以稍后再处理;全部处理完后冲突列表清空。
- 有一种冲突卡片底部写着**「本表内重复行」**:同一证件号 + 同一个小项同一个组别在表里出现了两次。这种卡片上可能一个字段都没高亮,是正常的——两条本来就可能一模一样。**保留已有** = 已经导入的那条报名保持不动,**使用新数据** = 用这一行的值覆盖它。
> 「从已有名单勾选」走的是同一个导入通道,人员匹配与冲突处理规则完全一致。
**「同名的另一个人」提醒(不是冲突)**
如果表里某人的证件号(或号码布)与库里「同名 + 同单位」的人不同,系统按**同名的另一个人**给他**新建档案**,并在导入结果里单独列出一块:`以下 N 人按同名的另一个人新建了档案(证件号 / 号码布不同)`,逐条显示 `姓名(单位):证件号 XXX → XXX;号码布 XXX → XXX`。这些行**已经导入成功、不会拦截**,只是提醒你核对证件号与号码布有没有写错;若确认是本人写错了号,到「基础数据 → 运动员」把档案里的号改回来、并删掉多出来的那条档案即可。
同一证件号在本表里出现多次时,导入结果里还会给一条 `证件号 XXXX 在本表中出现 N 次(同一人报名多个组别)` 的提示——这是**正常情况**,只提醒你别把不同的人写成同一个证件号。
种子等字段无法在勾选界面填写,仍需通过表格导入;号码布取自人员档案,勾选时会自动写入报名。团体报名登记的队员名单只存姓名,不会带动运动员档案。
---
## 11. 导出
页面分四个页签:**结果导出** / **基础数据** / **赛事项目包** / **规则包**。
### 11.1 结果导出(xlsx)
| 导出项 | 内容 | 文件名 |
| --- | --- | --- |
| 总表 | 总积分榜 + 单位奖牌榜 + 个人积分奖牌榜,一个工作簿 | `总积分榜.xlsx` |
| 全部 | 总表 + 全部分项,多 sheet 工作簿,适合归档打印 | `赛事成绩总表.xlsx` |
| 全部(单页) | 所有单位、所有项目、所有成绩**平铺在一张表**里(一个工作簿只有一张表),适合筛选与二次统计 | `赛事成绩总表(单页).xlsx` |
| 分项成绩表 | 选择一个小项导出成绩与积分 | `分项成绩表.xlsx` |
| 单位积分明细 | 选择一个单位,逐项列出得分来源 | `单位积分明细.xlsx` |
| 报名名单 | **本页下方的「报名名单」卡片**:按小项 / 组别 / 单位 / 批次筛选后导出报名数据(不填 = 全部)。13 列:小项编码、小项名、组别、单位编码、单位名、姓名、证件号、**号码布**、**批次**、性别、年龄、状态、备注;号码布按文本导出,前导零不会丢。**这是给人看的报表,不能拿去重新导入** | `报名名单.xlsx` |
| 报名名单(导入格式 · 汇总) | **同一张「报名名单」卡片下方的「导出(汇总·导入格式)」按钮**:13 列与报名导入模板**逐列一致**(项目编码 / 组别 / 单位编码 / 姓名 / 证件号 / 性别 / 年龄 / 号码布 / 种子 / 批次 / 状态 / 队员名单 / 队伍),所有行**汇总在一张工作表**里;筛选与上一行的「报名名单」完全相同,**导出的文件可以直接拿去重新导入** | `报名名单(导入格式).xlsx` |
| 报名名单(导入格式 · 分小项) | **同一张卡片下方的「导出(分小项·导入格式)」按钮**:同样这 13 列,按「小项名称@组别名称」**分成多张工作表**(重导时按**分工作表模板**那份口径解析,与导入规范第八节一致) | `报名名单(导入格式·分小项).xlsx` |
| 单位奖牌明细 | **在「积分榜 → 单位奖牌榜」页操作**:逐枚奖牌列出单位 / 大项 / 小项 / 组别 / 名次 / 奖牌 / 运动员、队,每个有奖牌的单位一张分表(末尾小计) | `单位奖牌明细.xlsx` |
| 个人积分总明细 | **在「积分榜 → 个人积分榜」页操作**:逐条列出单位 / 运动员 / 大项 / 小项 / 组别 / 名次 / 成绩 / 得分 / 来源,每个有得分的单位一张分表 | `个人积分总明细.xlsx` |
- 「分项成绩表」需先选择小项,「单位积分明细」需先选择单位;「报名名单」的四个筛选(小项 / 组别 / 单位 / 批次)**都可以留空**,留空就是不筛这一维度(全导);
- **队名(同一个单位派两个队时写的那个,见 4.12)写进「单位」列**:分项成绩表 / 全部 / 全部(单页)/ 报名名单 / 单位奖牌明细总表 / 单位积分总明细总表里,写的是 **`第一分公司二队`** 这种「单位名 + 队名」(队名留空时仍然只写 `第一分公司`)。⚠️ **这张报表里没有单独的「队名」列**(队名拼在「单位」列里),所以**报表件不能改完再导回去**(那会撞「同一个单位同一个队」的重复报名、报错拦下);**要整份重导,用「报名名单」卡片里那两个「导入格式」按钮**(见本节末「『报名名单』卡片里的两种『导入格式』导出」:13 列与报名模板逐列一致,可以直接导回;那份里「队伍」是**独立的一列**,不是拼在单位名后面的)。只改队名可以到录入页点「单位」格改,或走**导入模板**那条路;
- **联队(一条报名挂多个单位)在这几份导出件里的写法**(见 4.11):
- **「分项成绩表」「全部」「全部(单页)」的「单位」列**:写成联队全名 `第一分公司+第二分公司联队`(成员单位名写全,与导入表的 `F1+F2` 同构);**「备注」列**写清这条分给了谁、各多少,例如 `联队分拆:第一分公司 5 分(50%)、第二分公司 5 分(50%)`——「积分」列写的是**联队拿到的总分**(上例 10 分),每家的那一份看备注;
- **「报名名单」(报表件)**:「单位编码」列回写成 `F1+F2`(**这一列本身可以直接拿去重导**,不用手工改回单个单位)、「单位名」列写联队全名、「备注」列写 `联队分拆:第一分公司 50%、第二分公司 50%`(这张表没有积分列,所以只写份额比例)。⚠️ 但它是**报表**:**姓名列拼了队员、队名拼在单位名后面**,整个文件不能直接导回;要整份重导请用本节末「导入格式」那两个按钮——那份的「单位编码」同样写 `F1+F2`,而且姓名 / 队伍列都是能导回的写法;
- **按单位筛选导出时,成员单位也看得到这条报名**:「报名名单」按 F2 筛选,能导出「主单位是 F1、成员里含 F2」的联队报名(否则 F2 导出自己的名单会发现「没派人上场」);
- 「单位积分明细 / 单位积分总明细」「个人积分总明细」「单位奖牌明细」里联队的写法见 8.3;**没有联队的赛事,这些列与升级前逐字一致**。
- **三种「还没出结果」的行也照样占一行**(「分项成绩表」「全部」「全部(单页)」都是,逐格口径完全一致):
- **录了但还没发布**:成绩列写 **`分数未录入`**、名次与积分列写 `—`、状态列写「草稿」;
- **完全没有录成绩**(连草稿都没有):名次 / 成绩 / 积分三列都写 `—`(不是空、也不是 `0`)、状态列写「未录入」;
- **成绩已发布、但那一组还没结算**(通常是管理员关掉了「分批发布时实时更新榜单」,见 10.5):**成绩照常打印**(这一条确实跑出来了),名次与积分列写 `—`、状态列写「未结算」——这样一眼能看出是「还没结算」,而不是「算出来就是 0 分」;
- **「全部」与「全部(单页)」的区别**:两者内容同源,覆盖的都是全部小项的全部报名 / 成绩;「全部」把每个小项放成一张分表(多 sheet 工作簿),「全部(单页)」把所有行平铺进同一张表,每行前面补「大项 / 小项 / 组别」三列以便脱离表名也能看懂。单页表的列是:大项、小项、组别、名次、号码、单位、运动员/队、成绩、积分、状态、备注;
- **「单位奖牌明细」与「个人积分总明细」不在本页**,在「积分榜」页对应榜单的卡片头点「导出奖牌明细」「导出个人明细」(见 8.3);个人积分总明细里的「得分」与个人积分榜一致,不受榜单口径折算系数影响;
- 导出文件由浏览器直接下载,表头、合并单元格与字体已按打印模板预设。
**「报名名单」卡片里的两种「导入格式」导出**
同一个「报名名单」卡片,在原来那个「导出报名名单」(给人看的**报表**)下面还有一组**导入格式**导出:
| 按钮 | 导出来是什么 | 文件名 |
| --- | --- | --- |
| 导出(汇总·导入格式) | 所有行**汇总在一张工作表**里 | `报名名单(导入格式).xlsx` |
| 导出(分小项·导入格式) | 按「小项名称@组别名称」**分成多张工作表** | `报名名单(导入格式·分小项).xlsx` |
- 两个按钮导出的都是 **13 列、与「基础数据 → 报名导入」里下载的报名模板逐列一致**(**顺序就是这个**):项目编码 / 组别 / 单位编码 / 姓名 / 证件号 / 性别 / 年龄 / 号码布 / 种子 / 批次 / 状态 / 队员名单 / 队伍——**没有小项名称、单位名称与备注列**(那三列只有上面的报表件才有,重导用不着:「项目编码 + 组别」已经足够定位)。**导出的文件可以直接拿去重新导入**;
- 四个筛选(小项 / 组别 / 单位 / 批次)与报表**完全一样**,都留空 = 全导;权限也和报表相同,**访客也能导**;
- 卡片上的**表头语言**两个小按钮「**中文表头**」(默认)/「**英文表头**」**只影响下面这两个导入格式的导出**,对上面的「导出报名名单」**不生效**(界面上写明了这一点)。选英文时表头是规范列名:`event_code` / `category` / `team_code` / `athlete_name` / `id_card` / `gender` / `age` / `bib` / `seed` / `heat` / `status` / `member_names` / `squad`;
- **一条报名都没有时不是报错**:照样下载回一张**只有表头**的表(一眼看得出是「这次没有数据」);分小项那种格式里,本来就没人报名的组合不会出一张空表;
- ⚠️ 分小项导出时,只要有**小项名或组别名里带 `@`**(模板里明令禁止的字符,见《报名名单导入规范》8.1),会**直接报错并点名是哪一项**,不会静默丢掉那几十行;
- 重导回去要注意的三件事(号码布可能撞冲突面板、联队份额会变成均分、队员名单只增不减)见《报名名单导入规范》第九节「导出的名单怎么导回去」。
### 11.2 赛事项目包
服务端一次只打开一个赛事项目,页面上看到的数据全部来自「当前」的那一项,其余项目只是躺在数据目录里的数据。
**赛事项目列表**
- 列出数据目录下的全部项目,含项目名、更新时间与占用大小,当前打开的那一项带「当前」徽标;
- 每行的「切换为当前赛事」用于切换(仅管理员),切换过程见下面「导入后怎样才算生效」;
- 列表里出现「缺 event.db」的项目不可切换,说明该目录不是完整的赛事包。
**导出 zip**:包内含 `meta.yaml`、`event.db`、`uploads/`、`rules.yaml`,整包拷走即可在另一台机器复现整场赛事。`uploads/` 里除了会标、背景图与单位 logo,还包含**上传到赛事信息里的字体**(在 `uploads/fonts/` 下),字体设置也随赛事库一起走,导入后不用重新上传字体。
**导入 zip**(仅管理员):选择 `.zip`,可填「重命名」,勾选「覆盖同名项目」会先二次确认。导入只把数据解到数据目录,**不会自动切换当前赛事**,所以导入完成后页面会提示「已导入为 xxx,但它还不是当前赛事」。
**导入后怎样才算生效**
1. 在导入完成的结果框里点「立即切换并重启服务端」(也可以稍后在赛事项目列表里点该项目的「切换为当前赛事」);
2. 服务端把项目名写进**数据目录根下**的 `active_project.txt`(不在赛事项目目录里)后退出,由服务管理窗口自动拉起,并打开刚切换的赛事;下次启动即使不带启动参数,也仍然是这个赛事;
3. 期间页面显示「正在重启服务端…」,每 1.5 秒探测一次服务端是否回来,恢复后自动刷新页面(最多等 60 秒);
4. 超过 60 秒仍未恢复时,页面会提示打开服务管理窗口确认服务端状态,待其显示「运行中」后手动刷新本页。
> 切换会让服务端重启,正在录入的成绩页会短暂无法提交,请避开比赛进行中操作。
> 账号与会话存在**数据目录根下的 `system.db`**(系统库)里,属于整个系统而不属于某个赛事库,所以切换赛事**不会**让你退出登录;万一重启后页面变成只读访客视图,登录一次即可,忘记密码用 `scoreboard.exe passwd` 重置(见常见问题「忘记密码怎么办」)。
### 11.3 规则包
> 规则包文件放在 `%LOCALAPPDATA%\ScoreboardConsole\rules\`(安装包里附带的那份会在首次启动时复制过去;见部署指南 3.5)。
- **导出 rules.yaml**:导出积分模板、并列规则、破纪录加分、计分通道与项目覆盖;
- **导入**(仅管理员):
1. 选择 `.yaml` / `.yml` 文件(就是上面那个 `rules\` 目录里的);
2. 点「预览差异」,查看格式是否兼容、影响多少个小项、逐条改动;
3. 确认无误后点「确认导入并全量重算」,服务端会按新规则重算全部已发布积分。
> 规则导入会立即改变积分榜与大屏,且**不能一键撤销**,纠错需重新导入旧规则包。
### 11.4 基础数据(单位 / 大项 / 小项 / 组别)
「基础数据」页签有**导出**与**导入**两张卡片,用于批量维护基础数据(单位 / 大项 / 小项 / 组别)。
**导出基础数据包**:点「导出 xlsx」导出一个工作簿,含**四张工作表:单位 / 大项 / 小项 / 组别**(组别表带所属小项编码)。列名是中文表头;导出的文件可以直接原样导回来,识别到的差异为 0。导出是**只读下载**,不需要管理员权限(访客也能用)。
**导入基础数据包**(**仅管理员**):
1. 选择 `.xlsx` 文件(只认 xlsx:四张表装不进一个 CSV);
2. 点「**预览差异**」:先看到 `新增 N 条 / 更新 M 条 / 无变化 K 条 / 错误 K 条` 与**逐行变化**(哪个字段从什么变成什么),这一步**不写库**;
3. 确认无误后点「**确认写入**」才真正写库;**有错的行会被跳过,合法的行照常写入**(与报名导入一致);行级错误是中文并带**真实 Excel 行号**,例如 `单位 第 3 行:单位编码必填`。
几条现场要记住的规则:
- **按编码匹配**:单位 / 大项按编码,小项按编码,组别按「小项编码 + 组别名」;**存在就更新、不存在就新建**;
- **绝不删除**:文件里没有的行(表里没有、或整张工作表没放)**不会被删掉**,也不会被停用;
- **列不在表里 = 不动该字段**(**布尔列也一样**——把整列「启用」删掉再导回,**不会**把所有停用的单位/大项改成启用);**列在表里但格子留空 = 按该列的默认口径处理**:简称 / 颜色 / 场地 / 备注等文本列与年龄上下限会**清空**,权重留空按 1、启用 / 计分 / 计破纪录等布尔列留空按「是」,**排序留空则保持原来的值**(**四张表口径一致**,单位 / 大项留空同样不会被改写)。改数据前先想清楚这一点;
- **枚举列是唯一的例外:列在表里但格子留空 = 不改动,不是"取默认值"**。小项的**类型 / 结果模式 / 结果类型 / 比较方式 / 状态 / 平均口径**、组别的**性别**都属于这一类:留空就沿用这一行在系统里原来的值(**只有新建的行**才用默认值,例如新建组别时性别留空 = 不限)。这么定是为了防手滑——表格里误清一格,不会把一个已发布的小项打回「待录入」、也不会把「团体」改成「个人」;
- **表头行可以不在第一行**:从系统导出的包表头在第 4 行(上面是标题与副标题),手工整理的表表头在第 1 行,两种都能识别(识别范围是前 20 行);
- **枚举列要填系统里的英文规范值**(表头是中文,容易踩):类型 `individual` / `team` / `match` / `individual_team`,录入方式 `auto` / `manual`,成绩类型 `time` / `distance` / `count` / `score` / `none`,比较方式 `asc` / `desc` / `none`,小项状态 `pending` / `ongoing` / `finished` / `published`,平均口径 `valid` / `all`;布尔列(启用 / 计分 / 计破纪录)填 **是 / 否**;组别表的「性别」填 **男 / 女**(列在表里但格子留空 = 不改动;新建的组别留空 = 不限);
- **最稳的用法**:先「导出基础数据包」,在导出件上直接改,再导回来——表头与取值天然对得上;手工整理的表格请照导出件的表头写;
- 被「彻底删除」的单位不在导出件里;导入时如果有一行命中它的编码,**这一行整行跳过**(不更新它的任何字段,也不会把它恢复出来),并在导入结果里报一句 `单位 第 N 行:单位 XX 已被彻底删除,本行跳过(导入不会把隐藏的单位翻出来);要放回列表请先恢复该单位`——错误计入「错误 N 条」,其余合法的行照常写入。真要让这个单位回来,先到「基础数据 → 参赛单位」用「恢复」把它放回列表(见 10.1),再导入。
---
## 12. 变更历史
仿 Git 图谱的只读操作记录。
1. 顶部可筛选小项,以及「全部时间 / 近 24 小时 / 近 7 天」;
2. 左侧时间轴最新在上,节点显示动作(发布 / 撤销发布 / 编辑)、项目、操作人、时间与备注;
3. 点节点,右侧显示操作人、影响单位与成绩前后对比(diff);
4. 本页**不提供一键回滚**。纠错请到「成绩录入」:只错一条走「点成绩格(或「修改本条」)→ 改 → 重新发布本组」(见 4.10),整组要改才走「撤销发布 → 修改 → 重新发布」(见 4.7)。
---
## 13. 日志
审计日志,只读、不可删除,记录谁在什么时候改了什么。
1. 可按「**动作**」「实体」筛选,点「清除筛选」复位。**动作是子串模糊匹配、由服务端在全库范围执行**(填 `import` 能筛出**全部导入类动作**——报名名单导入、冲突决策、基础数据包、规则包、赛事包都认这个词;填 `entry` 能筛出成绩录入里的批次与批量操作;填 `team.purge` 能筛出单位删除),**实体筛选与分页作用于返回的最近 200 条窗口**;
2. 列表显示时间、操作人、IP、动作、实体、请求 ID;关键动作会带「关键」标记;
3. 点某行「对比」展开,查看改动前后的 JSON 差异;
4. **动作筛选不受 200 条窗口限制**(服务端按全库匹配后再取回),实体筛选与翻页只在窗口内;
5. 该页面仅管理员可查看。
> 本页是**业务审计**(谁在什么时候改了什么),只记**放行**的操作。想看「某次操作为什么被系统拦下」——比如保存被拒、导入报错、切页提示离线——那要看服务端写在数据目录 `logs\` 下的**两类日志文件**(放行类 / 拦截类):我们主动拦下的报错会写明中文原因、拦截点 `文件:行 函数名`、操作人与 requestId。位置、轮转与复盘步骤见[部署指南 · 服务端日志与拦截复盘](./部署指南.md#10-服务端日志与拦截复盘)。
---
## 14. 系统设置
页面分五个页签:**用户管理** / **登录有效期** / **备份** / **图片资源** / **赛事信息**。前四个需要管理员权限,非管理员只看到「赛事信息」(其余页签不显示)。
### 14.1 用户管理
| 操作 | 说明 |
| --- | --- |
| 新建用户 | 填写账号 *、显示名 *、角色 *(管理员 / 录入员)、初始密码 *(至少 8 位);新用户首次登录强制改密 |
| 编辑 | 修改显示名、角色、启用状态;账号创建后不可改 |
| 停用 | 二次确认后该用户无法登录,正在使用的会话也会失效 |
| 重置密码 | 生成随机密码,**只显示一次**,可复制后交给用户;旧密码立即失效 |
> 访客身份由系统默认提供,不需要也不允许建「访客账号」。
### 14.2 备份
- 列表显示备份文件名、来源、大小、创建时间;
- 点「立即备份」马上生成一份;
- 服务端默认每 5 分钟自动备份一次,自动、手动、发布前备份都按 `backup.keep`(默认 20 份)滚动保留;⚠️ `deploy\backup.bat` 额外产出的 `*-uploads-*.zip`(上传图片与字体)**不在**这个滚动清理里,要手工清理;
- 每行备份都有**「恢复」**按钮(**仅管理员**):用那份备份覆盖当前库——服务端会先自动留一份「恢复前安全副本」(`pre-restore-…db`,不参与滚动清理,**每类库只保留最近 5 份**,更旧的会被后续恢复自动清理),替换文件后优雅重启,页面自动等待刷新。**恢复是覆盖式的**(会丢备份时间点之后的改动),**恢复系统库会连账号与会话一起换掉**,**不会带回上传的图片与字体**;右侧「恢复说明」列出细节与停机手工恢复步骤(详见部署指南第 8 节)。
### 14.3 赛事信息
| 字段 | 说明 |
| --- | --- |
| 赛事名称 * | 必填 |
| 副标题 / 主办方 | 可选,显示在大屏顶部 |
| 赛事会标 | 图片,显示在大屏左上角。点「上传图片」选文件即可(png / jpg / webp / gif,单张不超过 5 MiB);上传的图片存在赛事项目目录的 `uploads/` 里,会随赛事包一起导出/导入 |
| 大屏标题 / 大屏副标题 | 大屏顶部标题区 |
| 大屏会标 | 图片,只对大屏生效;留空则用上面的「赛事会标」 |
| 大屏背景图 | 图片,铺满大屏底层;留空则用内置深色背景 |
| 轮播间隔(秒) | 控制大屏底部滚动条(奖牌榜 Top3 / 最新完成项目 / 公告)的切换间隔,5–120 秒 |
| 主题色 | 大屏主色,如 `#3482FF` |
| 个人积分榜上屏 | 开关;关闭后大屏不展示个人积分榜 |
| 个人榜奖牌列 | 开关,默认展示;关闭后个人积分榜不显示金 / 银 / 铜三列 |
| 标题字体 / 正文字体 | 下拉选择,分别作用于大屏标题与大屏正文;第一项是「默认(跟随系统)」,之后是四款内置字体与已上传的字体。只影响大屏画面,管理端界面字体不变 |
| 字体库 | 「上传字体」按钮与已上传字体列表(每行显示字体名与地址,可「删除」) |
改完点「保存」;未保存时显示「未保存」徽标,点「放弃修改」可还原。
**字体区块**
四款内置字体随程序分发,不用上传:`Noto Sans SC(思源黑体同源)`、`Noto Serif SC(思源宋体同源)`、`MiSans`、`Source Han Sans CN(思源黑体)`。区块底部的「预览」会按当前所选字体实时渲染一行中文,先看效果再保存。
上传自己的字体:
1. 在「字体库」点「上传字体」,选择本地字体文件;
2. 只支持 `.ttf` / `.otf` / `.woff` / `.woff2`,**单个文件不超过 20 MiB**;格式不符或超过上限会在上传前直接提示;
3. 上传成功后,新字体立刻出现在两个下拉里(按文件名显示);**文件名重复会被拒绝**,需要先删掉旧文件或改名后再传;
4. 字体文件落在**当前赛事项目目录的 `uploads/fonts/`** 下,列表里会显示它的地址 `/uploads/fonts/<文件名>`;文件名里的中文会保留,其他特殊字符会被换成下划线。
选好字体后点「保存」提交:服务端会校验字体是否真实存在,选了无效字体会被拒绝并给出中文提示。保存后大屏按新字体重新渲染;**字体文件加载失败时大屏自动回落到默认字体**,不会出现方块或空白。
删除已上传的字体:
1. 在「字体库」列表里点该行的「删除」,二次确认后生效;
2. **正在被标题字体或正文字体使用的字体不能删**,会提示「正在被大屏使用,请先在赛事信息里改掉标题/正文字体」:先把下拉改成别的字体并保存,再回来删。
> 字体文件就在赛事的 `uploads/fonts/` 里,所以**导出赛事项目包会连字体一起带走**,导入后直接可用、不用重新上传;字体设置存在赛事库里,也随包走(见 11.2)。
> 修改大屏标题、主题色、字体等会立即影响所有在线大屏,请避开颁奖或播报时段。
### 14.4 登录有效期
「登录有效期」页签(**仅管理员**)设置**这台机器上所有人的登录能待多久**。它是机器级配置(存在系统库 `system.db` 里),不随赛事项目包走。
| 项 | 说明 |
| --- | --- |
| 登录有效期(小时) | 可填 **1–720** 的整数(最长 30 天),默认 **24 小时**;原先固定 12 小时的做法已取消 |
| 当前会话将于 X 过期 | 页面顶部与右上角用户菜单里都会显示当前登录的到期时间 |
- **滑动续期**:只要在有效期内继续操作(两次操作的间隔不超过设定时长),到期时间会自动往后顺延——**不会因为「登录满 N 小时」被踢**。因此比赛期间可以从早用到晚不重新登录,例如把有效期设成 **72 小时**(三天);
- **改有效期不会当场踢人**:已经登录的会话不会在改设置的一刻被判定过期(库里到期时间不动),它们会在**下一次操作时按新的有效期续期**——调长会立即顺延(例如从 12 小时调到 72 小时,正在用的会话下次有请求就顺延成 72 小时),调短也只影响之后的续期,不会把正在用的人下线;
- 页面开着不动时,管理端每 10 分钟会自动续期一次,所以只要页面还开着就不会掉线;
- ⚠️ **不是「永不掉线」**:如果超过**设定的有效期**(默认 24 小时)一直没有操作(例如浏览器关了、机器关机过夜),再打开时仍会要求重新登录。
- 忘记密码时用 `scoreboard.exe passwd` 重置(见常见问题「忘记密码怎么办」)。
### 14.5 图片资源(清理没在用的图)
「图片资源」页签(**仅管理员**)列出 `uploads\` 里**没有被任何配置引用**的图片(也就是「孤儿」),用来清掉换图后留下的旧文件。表格显示预览、文件名、大小、修改时间,可单张「删除」或勾选后「删除选中」;删除前有危险确认框,**删掉不可恢复**。
什么算「被引用」——下面四处任意一处指向它,它就不算孤儿、不会出现在列表里:
- 赛事会标、大屏会标、大屏背景图(「赛事信息」页签里的三个图片字段);
- 任何一个**参赛单位的单位图标**(`logo` 字段)——**已被「彻底删除」的单位也算**,因为它还能被恢复,logo 得留着。
用法(典型的「换图后清旧图」):
1. 在「赛事信息」或「参赛单位」里把对应字段改成新图(或清空)并**保存**,旧图就没人引用了;
2. 到「图片资源」页签点「刷新」,旧图会出现在孤儿列表里;
3. 核对预览确认是那张没用的图,勾选 → 「删除选中」→ 确认。
- 若某张图在你打开页面之后**刚被配到别处**(比如别人同时改了单位 logo),服务端会**拒绝删除并在结果里说明被谁引用**——这是有意的「宁可漏删、不误删」;
- 这个页签**只管图片**;上传的字体在「赛事信息 → 字体库」里各自删除(被标题 / 正文字体引用的不能删,见 14.3);
- 这些图片与字体都是**文件**,在赛事项目的 `uploads\` 里:**备份的 `.db` 快照与「一键恢复」都不含它们**(见 14.2、常见问题 Q37)。
---
## 15. 修改密码
1. 输入原密码;
2. 输入新密码(至少 8 位)并再次确认;
3. 点「修改密码」;
4. 修改成功后所有会话作废,需要用新密码重新登录。
首次登录或密码被管理员重置后,会强制进入本页。
---
## 16. 关于
展示系统名称、版本号、构建时间、运行模式,以及技术栈与开源许可、字体清单(四款内置字体的用途与授权;给大屏换字体见 14.3)、键盘快捷键、部署信息(服务端端口、访问地址、赛事项目名)。
---
## 17. 大屏端使用
### 17.1 页面
大屏支持六个页面:
| 页面 | 内容 |
| --- | --- |
| 总积分榜 | 名次、单位(单位 logo + 单位名)、总分,以及名次升降箭头(约 2 秒后淡出) |
| 单位奖牌榜 | 名次、单位(带单位 logo)、金 / 银 / 铜、合计 |
| 个人积分奖牌榜 | 名次、姓名(姓名前显示所属单位 logo)、单位、总分、奖牌 |
| 分项成绩 | 最新已完成项目的成绩,单位列名字前显示单位 logo |
| 实时赛况 | 当前正在进行项目的实时排名(见下方说明) |
| 公告 | 管理端推送的公告:推送后先全屏展示,之后常驻底栏的「公告」槽位 |
**实时赛况**:专门给「现在正在比的项目」用,每一行显示**名次、运动员 / 队、单位(带单位 logo)、成绩**,按名次升序。
- **显示哪个项目**由管理端判定(见第 9 节的「实时赛况」卡片):优先按人工指定的项目,其次按项目排期(开始时间前后 30 分钟内),都没有时显示**最近发布过成绩的项目**——所以**在下一场开始之前,这一页会一直保持显示上一场的成绩**;
- **1 个项目单栏铺开,2 个项目自动左右分栏**(最多 2 栏,对应「两个项目时间撞在一起」的现场);
- 只显示**已发布**的成绩:配合分批发布,发一批这一页就更新一批(见 4.6);
- 同一个小项分了多个组别时,栏里显示**最近发布的那一组**,标题旁用「另有 N 组」标注;该项目还没有已发布成绩时栏内显示「该项目暂无已发布的成绩」;
- 每栏最多列前 10 个名次;一个项目都没有时整页显示「暂无进行中的项目」(刚切到本页、结果还没回来时显示「正在获取当前项目…」)。
> 单位 logo 取自「基础数据 → 参赛单位」里上传的图片(见 10.1),按行内文字大小显示,不会撑开行高;没传 logo 的单位不占位,图片临时加载不出来时保留占位、刷新后恢复,队名不会跳动。
> **联队(两个单位合并参赛)在大屏上怎么写**(见 4.11):「分项成绩」与「实时赛况」的**单位列写联队全名**——`第一分公司+第二分公司联队`,并且**把两个单位的 logo 都放上**(单位列宽会为该行实际要画的 logo 数留位置,第二个 logo 不会把名字挤成省略号);底栏「最新完成项目」那一行同样写联队全名。**单位奖牌榜、总积分榜本来就是逐单位一行,服务端已按份额拆好**(例:A、B 各 1 枚金、各 7.5 分),屏上不需要另做处理。**没有联队的赛事,大屏画面与升级前逐像素一致**。
> **队名(同一个单位派两个队时写的那个,见 4.12)同样写在大屏的单位名后面**:`第一分公司二队`——分项成绩、实时赛况、底栏「最新完成项目」三处都一样(同一个单位的两个队都进了名次时,两行只差队名,不写就分不出哪一行是谁);**单位奖牌榜、总积分榜上不写队名**。队名留空时画面与以前逐像素一致。
> 大屏的标题字体与正文字体取自「系统设置 → 赛事信息 → 字体」(见 14.3):可选四款内置字体,也可以上传自己的字体;上传字体加载失败时自动回落到默认字体,画面不会出现方块或空白。
> 除了 Console 开出来的本机大屏窗口,**局域网设备(另一台电脑、电视浏览器)打开 `http://<主机IP>:19540/display` 也能当大屏用**。这个地址不用手敲:管理端「大屏控制 → 局域网大屏」卡片里有**可复制的完整链接与二维码**(**第一条是常驻二维码,其余每条都能点「二维码」按钮临时出码**,见第 9 节)。这类设备会出现在管理端「大屏控制 → 在线大屏」列表里(带一个自动设备标签,可手动改名),也能被单独切页,用法见第 9 节;它们不受 Console 的 kiosk、防熄屏控制(另见常见问题 Q29)。
### 17.2 轮播与锁定
- Console 启动的多屏大屏窗口默认**每屏锁定一页**,不轮播;
- 在管理端「大屏控制」点「解锁」后开始整页轮播,**每 20 秒切换一页**;
- 公告页是手动触发的页面,不参与自动轮播;个人积分榜可在「赛事信息」里关闭上屏;「实时赛况」页参与轮播(见 17.1);
- 底部滚条固定有「公告」槽位:管理端推送过公告就一直显示最近那条,没有公告时显示「暂无公告」(见第 9 节);
- 点「锁定」可停在当前页。
### 17.3 明细覆盖层
- 管理端推送单位积分明细后,大屏右侧弹出半屏覆盖层,显示该单位每一分的来源;
- 覆盖层的表头是**项目 / 组别、运动员、名次、成绩、积分**五列:团体项目、按队内平均算出的团体分这类没有单个运动员的明细,「运动员」列显示**单位名**(不显示 `null`、也不留空格);
- **破纪录加分**那一类明细会在项目名后面多一个小标签 `破纪录`,一眼看出这几分不是名次分(人工调整的项目列本来就写着「人工调整」,不再重复打标签);
- **被改过的成绩**在那一行下面多一行小字,形如 `10:42 已修订(成绩录入笔误)`——大屏不能悬停、观众也离得远,所以时间只写几点几分、原因超过十几个字会截断(完整的时间、原因与操作人在管理端明细的角标悬停里看);
- 默认 **60 秒后自动关闭**并恢复轮播;
- 管理端「关闭大屏明细」可立即关闭。
### 17.4 断线与自愈
- 与后端断开时,大屏顶部显示离线角标,并继续展示本地缓存的最近一份快照;
- 连接恢复后自动拉取最新数据;
- 大屏每 24 小时自动重载一次,Console 同时启用防熄屏。
### 17.5 调试标识
窗口化(带标题栏的调试窗口)**且没有全屏**时,右上角会显示一行「实例 x · 屏 x」,用来分辨这块屏是哪个实例。除此之外没有别的调试标识——**数据版本号 `vN` 角标已经去掉,任何情况下都不再显示**;需要核对某块屏有没有跟上服务端时,用管理端仪表盘「实时连接」里的「版本 N」对照。
- **kiosk 全屏窗口**(多屏时每屏一个)不显示任何调试标识,正式上屏的画面是干净的;多屏 kiosk 也不响应 F11。
- 单屏窗口化窗口按 **F11** 全屏后,自绘标题栏与「实例 · 屏」会一起消失、画面铺满整块屏;再按一次 F11 回到窗口化,标题栏与标识一起回来。
### 17.6 赛事日程侧边栏
管理端在「大屏控制 → 赛事日程」里配了**手填日程**并打开开关后,**每一块大屏**上都会多出一块**侧边栏**(默认在**右侧**、占屏 **22 %**,左右与宽度可在管理端改)。它**叠在当前页之上**:**不改当前页、不停轮播**——大屏本来在轮播就继续轮,锁着就继续锁着,侧边栏只是多出来一层(见使用手册 9.2)。
- **一条竖向进度轴 + 三态节点**:**已完成**(实心节点 + 整条淡化保留)、**当前**(节点放大带光晕,最醒目)、**未开始**(低对比);面板顶部一行读数 **`已完成 x / 共 y`**;
- **「当前项」= 第一个没勾「已完成」的条目**——**不按时间判断**(时间是完全手填的自由文本,`上午` / `待定` 这种没法可靠解析);
- **备注默认上屏**(例如每条的「检录 08:00」),管理端可以整体关掉,关掉后只显示时间与标题;
- **日期/时间只是照抄你填的字**:系统**不解析、不比较、不按时间排序**,**上屏顺序 = 管理端里的顺序**。
> ⚠️ **它不是「完整日程公示」**:条目放不下时,面板会**围绕当前项开窗**——当前项固定在显眼位置、前后各显示若干条,**已完成的与很靠后的条目会滚出视图**(被截住的方向上会写一句「上方 / 下方还有 N 项」)。要把**完整**日程公示出来,请用轮播页或另行打印公示,**别指望这条侧边栏**。
**排版**:字号按文本长度与可用高度**自适应**,但有**硬上下限**——**宁可少显示几行,也不缩到看不清**;长标题最多 3 行、长备注最多 2 行,超出的部分按显示宽度**省略**;时间与备注比标题小一档(0.8 倍,同样有下限)。**1080p 与 4K 都按屏幕等比缩放**(4K 上字与面板一起放大,不会多放大一次)。
**外观**:**深色半透明 + 毛玻璃**;**不支持毛玻璃的老浏览器会退化成更不透明的深底**(保证字看得清),功能不缺。系统开了「减少动态效果」(`prefers-reduced-motion`)时不做入场动效。
**什么时候它会自己收起来**(**开关状态不动**,事情过去自动回来):
- 管理端推送的**积分明细覆盖层**开着期间(见 17.3);
- **全屏公告**正在播期间(公告退场就回来)。
**关掉之后**:管理端把总开关一关,大屏上**连一个元素都不会留下**,画面与**没有这个功能时逐字节一致**;某一块屏单独设成「强制关」时也一样(只影响那一块屏)。
---
## 18. 常见操作问题
**Q:为什么录入的成绩大屏上没有?**
草稿不会上屏。需要点「发布」(或 `Alt+Enter`),发布成功后立即更新。
**Q:发布后发现有错怎么办?**
只错一条成绩:到「成绩录入」找到那一行,**点那一格(或点「修改本条」)→ 填原因 → 确认 → 改对 → 重新发布本组**,只动这一条(见 4.10)。
整组要改:点「撤销发布」→ 修改 → 重新发布。撤销会作废该组积分流水,大屏回退;全程可在「变更历史」追溯。
整组 / 整批**录错了、要从头再来**(连成绩内容一起清掉):用工具栏上的「**清空本组 / 清空本批**」——它同样收回分、退榜并记进「变更历史」,区别只在**成绩内容留不留**(撤销发布保留、清空清掉,见 4.7)。
**Q:并列名次怎么显示?**
成绩相同(或手动名次相同)即视为并列,显示同一名次,例如两个「3」。积分按规则包里的并列口径计算,默认是「顺延」:并列第 3 各得第 3 名的分,无第 4 名,下一名是第 5 名。奖牌也按并列处理,并列第 1 各记 1 金、无银牌。
**Q:为什么「发布」按钮是灰的?**
可能原因:当前是访客未登录(只读)、处于示例数据模式,或校验存在错误。页面会给出对应提示。
> 顶部显示「连接中断」不会再禁用按钮:实时推送断了只意味着数据可能不是最新,写操作照常提交并由服务端校验。
**Q:为什么页面显示「示例数据」?**
说明前端连不上后端或接口未就绪,此时操作不会写入真实赛事。请检查 Console 里服务端是否为「运行中」,恢复后刷新页面。
**Q:大屏上的积分明细怎么关?**
在「积分榜」页点「关闭大屏明细」,或在「大屏控制」里锁定 / 切换页面;不操作时 60 秒后自动关闭。
**Q:公告怎么发?多久消失?**
在「大屏控制 → 公告」输入文字,设置「滚动时长」(5–120 秒,即全屏展示的秒数)后点「推送公告」:大屏会先全屏显示,到时间后自动回到原来的页面,公告**不会消失**,会留在底栏「公告」槽位继续显示,直到你推一条新的或点「清除公告」。公告卡片上会显示当前公告正文与「当前公告:有 / 无」;新开的大屏、断线重连后会把当前公告再全屏播一遍(默认 15 秒)后留在底栏。
**Q:怎么切换到另一个赛事项目?**
在「导出 → 赛事项目包」的**赛事项目列表**里找到目标项目,点「切换为当前赛事」:服务端会退出并由服务管理窗口自动拉起,页面显示「正在重启服务端…」,恢复后自动刷新,同时记下「上次打开的赛事」,下次启动即使不带参数也仍打开它。详见部署指南第 8.5 节。**别**用 Console 的 `config.json` 给 `server.args` 加 `-project` 来切赛事:那样每次启动都会优先打开并写回这个项目,页面里切完、重启后又被拉回去。
**Q:导出的文件在哪里?**
结果导出和赛事包由浏览器下载到默认下载目录;服务端自身也会在数据目录下的 `exports\` 里生成临时包(导出完成后自动删除)。数据目录默认是 `%LOCALAPPDATA%\ScoreboardConsole\data`,详见部署指南第 3.4 节。
**Q:登录多久会过期?**
默认 **24 小时**,可由管理员在「系统设置 → 登录有效期」里改成 **1–720 小时**(最长 30 天);比赛期间建议设成 72 小时。会话是**滑动续期**的:有效期内继续操作会自动顺延到期时间,不会因为「登录满 N 小时」被踢;但超过设定的有效期一直没操作(比如浏览器关了、机器关机过夜),就需要重新登录。当前到期时间在右上角用户菜单与「系统设置 → 登录有效期」里都能看到。
**Q:为什么登录失败次数多了会被暂时拒绝?**
登录有频率限制(每个 IP 每分钟 5 次),写操作也有频率限制(每个用户每分钟 120 次)。稍等一分钟再试即可。
**Q:为什么有些页面 / 按钮看不到或不可用?**
权限按角色控制:访客只能只读;变更历史、日志、系统设置、备份、用户管理、规则包与赛事项目包导入需要相应角色。请用对应账号登录。
**Q:为什么点「发布」还得多选一次?**
因为**这一次发布的「口径」要现选**(录入页原来的常驻勾选框已经取消)。窗口里二选一,**默认是「只更新名次(不计分、不发奖牌)」**,「按决赛成绩发布」才计分发牌、榜单跟着更新。
- **每次打开都回到默认那一项**,**不吃上一次的选择**——这是故意的:避免「换个小项再点发布,把预赛当成决赛算分」这种最贵的错法;
- **取消 = 什么都不发生**;`Alt+Enter` 走同一个窗口;
- ⚠️ **成绩审核页不一样**:那里仍然是发布按钮旁边的**常驻勾选框**(勾上才计分发牌)。两页口径一样,只是入口形状不同(见 4.5、第 5 节)。
**Q:人多的项目(3 公里、5 公里)里怎么快速找到某个人?**
在「成绩录入」页工具栏 **「批次」下拉右边**的搜索框里输入**姓名或号码布**:边打边筛(大小写不敏感、首尾与全角空格都当空白),号码布按**数字口径**比——`007` 搜 `7`、`7` 搜 `007` 都能找到;命中的字会**高亮**,旁边显示 `找到 N 条 / 共 M 条`(M 是当前批次口径的总行数)。清除有三种:输入框的 × 按钮、在输入框里按 `Esc`、「清除搜索」;**换小项 / 换组别会自动清空搜索**。搜索范围是姓名 / 队员名单 / 队员(含号码布)/ 行号码布,**不含单位名**。
⚠️ 两条要记住:
1. **搜索只影响表格显示,不影响发布范围与进度**(界面上也写着这行小字):筛完再点「发布」,发的仍是这个小项 + 这个组别里**所有已填的成绩**;进度条的「已录 x/y」也仍是**该批次总人数**;
2. **粘贴跟着屏幕走**:搜索状态下按 `Ctrl+V` 只往**看得见的行**填(被筛掉的行不会被写到,免得第二条成绩静默写到看不见的人身上);要按原来的行序粘贴,请先清除搜索。