{{ option.desc }}
+ +在下方表格中点击一行,或在上方选择小项,即可查看组别与计分通道。
+ +| 代码 | +名称 | +类型 | +录入方式 | +成绩 | +比较 | +计分 | +权重 | +状态 | +操作 | +
|---|---|---|---|---|---|---|---|---|---|
| {{ event.code }} | +{{ event.name }} | +{{ labelOf(EVENT_TYPE_OPTIONS, event.eventType) }} | +{{ labelOf(RESULT_MODE_OPTIONS, event.resultMode) }} | +{{ labelOf(RESULT_TYPE_OPTIONS, event.resultType) }} | +{{ labelOf(COMPARE_OPTIONS, event.compare) }} | ++ + {{ event.scored ? '计分' : '不计分' }} + + | +{{ event.multiplier }} | +{{ labelOf(STATUS_OPTIONS, event.status) }} | +
+
+
+
+
+ |
+
|
+
+
+
+ {{ selectedSportId === null ? '请先选择或新增大项' : '该大项下还没有小项' }}
+
+ 小项是最小计分单位,组别与计分通道都挂在它下面
+ |
+ |||||||||
当前小项的计分通道(名次来源 → 积分模板 → 录取名次):
+| 代码 | +全称 | +简称 | +主题色 | +排序 | +状态 | +操作 | +
|---|---|---|---|---|---|---|
|
+
+
+
+ 加载中…
+ |
+ ||||||
| {{ team.code }} | +{{ team.name }} | +{{ team.shortName ?? '—' }} | ++ + — + | +{{ team.sortOrder }} | ++ + {{ team.active ? '启用' : '已停用' }} + + | +
+
+
+
+
+ |
+
|
+
+
+ {{ search === '' ? '还没有参赛单位' : '没有匹配的单位' }}
+ 单位代码用于导出与排序,新增后不可重复
+ |
+ ||||||
停用为软删除:历史成绩与积分流水保留,新报名不再可选该单位。
+只有管理员能查看与创建备份。
+{{ loadError }}
++ 最近一次备份:{{ formatDateTime(latest.createdAt) }} + ({{ latest.reason === 'manual' ? '手动' : '自动' }}) +
+ +| 文件名 | +来源 | +大小 | +创建时间 | +
|---|---|---|---|
| {{ row.name }} | ++ + {{ row.reason === 'manual' ? '手动' : '自动' }} + + | +{{ formatSize(row.size) }} | +{{ formatDateTime(row.createdAt) }} | +
+ 备份文件存放在 data/backups/,滚动保留最近 20 份,不随 git 提交。
+ 服务端暂未提供一键恢复接口,恢复需在停机状态下手工执行:
+
systemctl stop scoreboard),避免恢复过程中继续写入。
+ event.db 改名备份,确认恢复失败还能退回。
+ event.db,同时删除 event.db-wal 与 event.db-shm。
+ + 恢复会丢弃备份时间点之后的所有改动(自动备份间隔 5 分钟)。现场先改 IP 切换备机、再考虑恢复, + 通常比原地恢复更快。 +
+只有管理员能修改赛事信息,当前账号为只读。
+{{ saveError }}
+ ++ 修改大屏标题、轮播间隔或主题色会立即影响所有在线大屏,保存前请确认现场没有正在进行的颁奖或播报。 +
+ ++ before / after 不是合法 JSON,下面按原文对照显示。 +
+ +{{ before ?? '—' }}
+ {{ after ?? '—' }}
+ | 字段 | +变更前 | +变更后 | +类型 | +
|---|---|---|---|
| {{ row.path }} | +{{ row.before }} | +{{ row.after }} | ++ + {{ CHANGE_LABEL[row.change] }} + + | +
{{ pretty(before) }}
+ {{ pretty(after) }}
+ 只有管理员能管理用户,当前账号为只读。
+{{ loadError }}
+ +| 账号 | +显示名 | +角色 | +状态 | +最近登录 | +操作 | +
|---|---|---|---|---|---|
| + {{ row.username }} + 待改密 + | +{{ row.displayName }} | +{{ roleLabel(row.role) }} | ++ + {{ row.active ? '启用' : '停用' }} + + | +{{ row.lastLoginAt === null ? '从未登录' : formatDateTime(row.lastLoginAt) }} | ++ + + | +
{{ formError }}
+ +| 组件 | +用途 | +许可 | +
|---|---|---|
| {{ item.name }} | +{{ item.usage }} | +{{ item.license }} | +
| 字体 | +用途 | +授权 | +
|---|---|---|
| {{ font.name }} | +{{ font.usage }} | ++ {{ font.license }} + {{ font.note }} + | +
| 位置 | +按键 | +作用 | +
|---|---|---|
| 成绩录入 | ++ + +{{ key }} + + | +{{ item.desc }} | +
| 大屏 | ++ + +{{ key }} + + | +{{ item.desc }} | +
+ 本系统为内部赛事使用;MiSans 字体授权仅限内部赛事,对外分发前请替换为 OFL-1.1 字体。 +
++ + 分值可正可负,类别为处罚 / 补分 / 更正,理由必填;作废会同时作废对应积分流水。 + + + 本次运动会扣分 / 处罚完全在系统外处理,系统只负责成绩分(02 第 4 节)。 + 功能与数据表已保留,以后赛事开一个开关即可启用。 + +
++ 读取规则包失败:{{ ruleError }},当前按「关闭」处理。 +
+| 单位 | +分值 | +类别 | +理由 | +关联项目 | +状态 | +时间 | +操作 | +
|---|---|---|---|---|---|---|---|
| + {{ teamLabel(item.teamId) }} + 本地 + | ++ {{ item.delta > 0 ? '+' : '' }}{{ formatPoints(item.delta) }} + | +{{ categoryLabel(item.category) }} | +{{ item.reason }} | +{{ eventLabel(item.eventId) }} | ++ 已作废 + 有效 + | +{{ formatDateTime(item.createdAt) }} | ++ + | +
+ 表头、合并单元格与字体都已按打印模板预设,导出即可直接打印。总表与全部导出由服务端合成一个多 sheet 工作簿。 +
+ +{{ option.desc }}
+ +
+ 包内含 meta.yaml + event.db +
+ uploads/ + rules.yaml(字体可选)。
+ 整包拷走即可在另一台机器复现整场赛事。
+
导入赛事包会替换整库数据,只有管理员可操作。
+ +{{ projectError }}
+ + + +如需立即切换到这个赛事,请到「系统 · 赛事信息」确认配置后重启服务端。
++ 导出为 YAML,含积分模板、并列规则、破纪录加分、计分通道与项目覆盖,可直接给另一场赛事复用。 +
+ +导入规则包会全量重算积分,只有管理员可操作。
+ +导入分两步:先 ?preview=1 预览差异,确认后再落地。
{{ rulesError }}
+ + + +| 类型 | +对象 | +变化 | +说明 | +
|---|---|---|---|
| {{ row.kind }} | +{{ row.target }} | ++ + {{ CHANGE_LABEL[row.change] ?? row.change }} + + | +{{ row.detail }} | +
+ 以下项目编码在当前赛事库中不存在,导入时会被跳过:{{ rulesPreview.unknownEvents.join('、') }} +
+ ++ 规则已落库,服务端重算了 + {{ rulesApplyResult.recalculatedLedgerRows }} + 条积分流水;大屏会随实时推送自动刷新。 +
+
+ 服务端 /api/audit-logs 只支持按实体与操作人过滤,暂不支持 action 参数,
+ 因此筛选与分页作用于最近 {{ WINDOW_SIZE }} 条记录。
+
{{ loadError }}
+ +| 时间 | +操作人 | +IP | +动作 | +实体 | +请求 ID | +详情 | +
|---|---|---|---|---|---|---|
| {{ formatDateTime(row.createdAt) }} | +{{ operatorLabel(row) }} | +{{ row.ip ?? '—' }} | ++ {{ row.action }} + 关键 + | ++ {{ row.entityType }} #{{ row.entityId }} + | +{{ row.requestId ?? '—' }} | ++ + | +
|
+ |
+ ||||||
+ + 确认破纪录会生成加分流水并更新纪录库;加分档位 {{ bonusMode }},与成绩积分相互独立(不随权重翻倍)。 + + + 规则包 `recordBonus.enabled = false`(02 第 3 节)。疑似破纪录仍会列出,但「确认加分」不会生成加分流水; + 以后开一个开关即可启用,档位与分值已预置。 + +
++ 读取规则包失败:{{ ruleError }},当前按「关闭」处理。 +
+| 小项 | +组别 | +单位 / 运动员 | +成绩 | +原纪录 | +档位 | +加分 | +操作 | +
|---|---|---|---|---|---|---|---|
| + {{ item.eventName }} + {{ item.eventCode }} + | +{{ item.categoryName }} | ++ {{ item.teamName }} + {{ item.athleteName }} + | +{{ item.resultText }} | +{{ item.recordText }} | +{{ LEVEL_LABELS[item.level] }} | ++{{ formatPoints(item.bonusPoints) }} | ++ + + | +
+ 「确认加分」在 recordBonus 关闭时不可用,避免生成无规则的积分流水。 +
+| 档位 | +成绩 | +保持者 | +单位 | +达成时间 | +来源 | +当前 | +
|---|---|---|---|---|---|---|
| {{ LEVEL_LABELS[record.level] }} | +{{ record.resultText }} | +{{ record.holderName ?? '—' }} | +{{ record.holderTeamId === null ? '—' : teamLabel(record.holderTeamId) }} | +{{ formatDateTime(record.achievedAt) }} | +{{ record.source === 'current' ? '本届' : '历史' }} | ++ 当前 + — + | +
| 单位 | +运动员 / 队 | +成绩 | +名次 | +状态 | +积分 | +对比 | +
|---|---|---|---|---|---|---|
| + {{ row.teamShort || row.teamName }} + | +{{ row.athleteName || row.memberNames?.join('、') || '—' }} | +{{ row.resultText || '—' }} | +{{ row.rank ?? '—' }} | +{{ statusLabel(row.status) }} | +{{ formatPoints(row.points) }} | ++ + | +
+ {{ compareMode === 'row' ? '选中一行查看它单独的得分影响' : '本次发布不会改变任何单位的分数' }} +
++ 系统配置类接口对 Guest 一律 403(devdocs/08 第 2 节),因此这里的写操作按钮全部禁用; + 登录管理员账号后即可操作。 +
+ +数据加载失败:{{ data.error }}
+ +