📖 目录
1. 系统概览 #
本系统是一套面向跳绳比赛的实时成绩管理平台,支持比赛建档、项目编排、运动员分组、场地分配、裁判执裁、成绩录入、实时大屏展示与导出统计的全流程。
1.1 五大端的能力矩阵
| 端 | 主要用户 | 核心功能 | 访问方式 |
|---|---|---|---|
| 管理员端 | 比赛管理员 | 建赛、项目、组别、场地、运动员、裁判分配、大屏配置、成绩导出 | 浏览器访问 admin.html |
| 裁判员端 Web | 裁判员 | 登录、执裁、成绩录入(计数赛 + 规定赛三角色) | 浏览器 judge.html(手机/平板) |
| 裁判员端 小程序 | 裁判员 | 同上(移动体验更佳) | 微信小程序搜索 |
| 大屏展示端 | 现场观众 | 实时成绩展示、场次切换动画、赛后庆祝 | 浏览器 display.html(大屏幕) |
| Android App / iOS App | 裁判员 | 等同小程序,多端框架打包 | 多端应用模式构建 |
1.2 技术架构(极简版)
2. 系统入口与登录 #
2.1 三大端入口
访问部署后的主域名 https://你的域名/,进入系统门户:
2.2 默认账号
| 角色 | 编号 / 账号 | 密码 | 备注 |
|---|---|---|---|
| 管理员 | 17653420201 |
环境变量配置 | 通过 ADMIN_PASSWORD 环境变量设置,无硬编码默认值 |
| 裁判员 | 自行注册 | 自行设置(必填,至少 4 位) | 注册后需管理员审核通过 |
• 管理员密码通过环境变量
ADMIN_PASSWORD 配置,不再有硬编码默认值• 裁判员密码必填,至少 4 位,无默认密码
• 登录失败 5 次自动锁定 5 分钟(管理员 + 裁判员双端)
• 锁定期间即使输入正确密码也会被拒绝,5 分钟后自动解锁
• 管理员可在「审计日志」页面手动解除锁定
3. 管理员端使用 #
管理员端是整个系统的"驾驶舱",通过左侧导航切换功能模块:
3.1 侧边栏导航
3.1.1 比赛管理
创建一场新比赛,作为所有数据(项目、组别、场地、运动员、成绩)的顶层容器。
display.html。
3.1.2 项目管理
管理比赛中的所有竞赛项目(如 30 秒单摇、3 分钟单摇接力、个人花样、规定套路等)。
• 计数赛(timing):1 名裁判计数 30 秒/3 分钟内的跳绳个数,得分 = 跳绳个数
• 规定赛(prescribed):3 名裁判分别评分(T1 创意 + T2 完成 + T3 主裁扣分),满分 100
• 花样赛(freestyle):多角色裁判(DP/DM/DR 难度分 + 完成分 + 创意分 + 规定扣分 + 主裁扣分),按官方计分规则
3.1.3 赛事组别
为比赛划分组别(如「男子组 - 三年级」「女子组 - 四年级」「混合组 - 五年级」「不限性别」),便于成绩分组统计。
3.1.4 场地管理
这是系统的核心调度界面,用于把"裁判员 + 运动员 + 项目"三者绑定到具体场地。
• 一个场地通常安排 3-8 名运动员,避免选手等待过长
• 规定赛场地需要 3 名裁判同时在岗(主裁判 + 创意 + 完成)
• 计数赛只需 1 名裁判(或 1 名计数 + 1 名计时分工)
3.1.5 运动员管理
批量导入 · 分组校验详解
系统采用两层防护机制,确保只有分组正确的运动员才能被导入:
| # | 姓名 | 学校 | 分组 |
|---|---|---|---|
| 1 | 张三 | 清华附小 | 青年组混合组 ✓ |
| 2 | 李四 | 北大附小 | 少年组 分组不匹配:运动员所属分组[少年组]不在赛事组别中 |
导入完成后,系统会弹出导入结果汇总:
失败记录支持:📥 导出 Excel(便于修正后重新导入)、重新导入失败记录(快速重试)。
• 运动员的「分组」字段必须与「赛事组别」中已配置的组别名称完全一致(含空格、全半角)
• 若赛事尚未配置任何组别,则所有运动员均可通过分组校验(视为不限组别)
• 分组为空的运动员不会触发校验,可正常导入
• 双层防护:预览阶段前端校验标红提示 + 提交阶段后端再次验证,确保数据一致性
3.1.6 大屏管理
在管理员端无需打开大屏窗口,就能直接调整大屏的呈现样式。
3.1.7 成绩总览
查看、修改、导出所有已录入的成绩。
• 计数赛专用:场地号、场次号、姓名、单位、项目、类型、成绩(7 列)
• 规定赛专用:场地号、场次号、姓名、单位、项目、类型、成绩、T1(创意)、T2(完成)、T3(主裁扣分)(10 列)
• 花样赛专用:场地号、场次号、姓名、单位、项目、类型、最终成绩、难度总分、完成均值、创意均值、规定扣分、主裁扣分、排名(13 列)
• 混合导出:通用 7 列,每行根据类型自动显示"计数赛 N 个"或"规定赛 N 分"或"花样赛 N 分"
• 统计表已优化
@media print 样式,打印预览时会自动带上边框• 推荐在 Chrome 浏览器中打印 → 设置边距为"默认"或"无"以获得最佳效果
3.1.8 裁判员管理
• 禁用(橙色)→ 点击后账号停用,裁判员无法登录
• 启用(灰色)→ 点击后账号恢复,裁判员可正常登录
• 审核状态(独立显示):表示裁判员是否通过了管理员审核,只有"待审核"和"审核通过"两种
• 启用/禁用(切换按钮):审核通过后才出现,用于临时停用或恢复裁判员登录权限
• 两者完全独立:禁用裁判员不影响其审核通过状态,启用也不需要重新审核
3.1.9 审计日志
记录所有登录(成功/失败/拒绝)、成绩提交、账号锁定/解锁操作,生产事故可一键回溯"谁在什么时间做了什么"。
4. 裁判员端 Web 版 #
4.1 登录与执裁任务选择
judge.html,输入裁判员编号 + 密码。错误时密码框会变红(编号不存在时编号框变橙色),并显示引导按钮。
• 单点登录:同一裁判员账号同一时间只能在一个设备上登录(不限 Web 或小程序)
• 失败锁定:密码错误 5 次自动锁定 5 分钟,锁定期间即使输入正确密码也会被拒绝
• 断网提示:网络断开时页面顶部显示红色断网横幅,恢复后自动消失
• 加载状态:数据加载时显示全屏加载遮罩,防止误操作
首次访问
judge.html 时,手机浏览器会提示「添加到主屏幕」。安装后即可全屏使用,体验接近原生 App。
4.2 计数赛执裁流程
• ×2:计数 × 2(用于多人同时跳)
• 弃权:标记为弃权
4.3 规定赛执裁(3 个角色)
规定赛由3 名裁判员分工评分,各角色登录后会自动进入对应执裁界面(judge-head.html / judge-creative.html / judge-completion.html)。
| 角色 | 页面 | 打分范围 | 说明 |
|---|---|---|---|
| 主裁判 (T3) | judge-head.html |
扣分 0-100 | 勾选犯规减分(如脚触地 +5、绳触地 +5)和取消资格项;得分 = 100 − 扣分 |
| 创意裁判 (T1) | judge-creative.html |
0-20 分 | 整体创意编排 + 现场表现效果 |
| 完成裁判 (T2) | judge-completion.html |
0-80 分 | 动作准确性 / 熟练性 / 合拍性 / 一致性 |
最终得分 = T1 + T2 − T3扣分(满分 100)。每位裁判独立提交,前端实时显示"我已提交"状态,3 名裁判全部提交后大屏自动显示最终成绩。
4.4 花样赛执裁(多角色)
花样赛按官方计分规则实现多角色执裁,各角色登录后进入对应执裁界面:
| 角色 | 打分范围 | 说明 |
|---|---|---|
| 难度裁判 DP | 难度分 | 评定难度动作分值 |
| 难度裁判 DM | 难度分 | 评定难度动作分值(与 DP 独立打分) |
| 难度裁判 DR | 难度分 | 评定难度动作分值(与 DP/DM 独立打分) |
| 完成裁判 | 扣分 0-5 | 完成质量扣分(0/1/2/3/5 分档) |
| 创意裁判 | 0-10 分 | 创意编排评分 |
| 规定扣分裁判 | 扣分 | 规定动作缺失扣分 |
| 主裁判 | 扣分 | 总体印象扣分 |
计分规则:难度分 = min(50, DP + DM + DR 总和);最终成绩 = 难度分 + 完成分(×0.5) + 创意分(×0.5) − 规定扣分 − 主裁扣分。
任一维度(如完成分)所有裁判提交后,大屏立即显示该维度分数,不用等所有维度完成。方便现场观众和教练实时了解评分进度。
4.5 SSE 实时同步
计数赛页面使用 SSE(Server-Sent Events)实时推送技术:
- 裁判员提交成绩后 < 300ms 同步到其他裁判端和大屏
- 无需手动刷新,其他裁判端自动看到最新提交状态
- SSE 连接断开后自动重连,保留 30 秒版本号轮询作为 fallback
4.6 查看历史成绩
小程序端提供"我的历史"页面(history.wxml),可查看本裁判员历史上报的所有成绩,便于赛后回顾和申诉。
5. 裁判员端 小程序 / App #
移动端(微信小程序 / Android / iOS App)使用流程与 Web 版完全一致,但 UI 针对小屏做了优化(数字键盘更大、按钮更易点击)。
5.1 登录与界面
• 编号不存在 → 编号框橙框 + 错误卡片带 ⚠ 图标 + 「立即注册」快捷按钮
• 账号审核中 → 带 ⏳ 图标
• 已禁用 → 带 🔒 图标
• 已在其他设备登录 → 带 🔒 图标 + 「账号已在其他设备登录,请等待当前用户退出后再尝试」
5.2 Android / iOS App 构建
- 在微信开发者工具中切换到「多端应用模式」。
- 点击菜单「工具」→「多端框架」→「生成 Android 工程」 / 「生成 iOS 工程」 → 自动生成原生项目壳。
- Android:使用 Android Studio 打开生成的工程 → 编译 APK。
iOS:使用 Xcode 打开 → 配置证书 → 编译 IPA。 - App 内核与小程序完全一致,无需重复开发业务逻辑。
•
project.miniapp.json 中需包含 mini-android / mini-ios 段(首次生成时开发工具会自动创建)• 详见
APK快速构建指南.md
6. 大屏展示端 #
大屏端面向现场观众,通过浏览器全屏运行,使用 SSE 实时同步裁判员录入的成绩(延迟 < 300ms)。
6.1 启动与全屏
display.html,浏览器自动连接到管理员设置的比赛。
F11(或点击右上角 ⛶ 按钮)→ 全屏显示,Esc 退出。
大屏通过
EventSource 连接 /api/display/:id/stream SSE 端点,裁判员提交成绩后 < 300ms 推送到大屏。SSE 断开后自动重连,同时保留版本号轮询作为 fallback。
6.2 界面布局
6.3 场次切换动画
当管理员切换到下一场次时,大屏会显示"第 X 场次 → 第 Y 场次"的过渡卡片,旧场次卡片向左滑出,新场次卡片从右滑入。
6.4 赛后庆祝特效
当某场次所有运动员成绩录入完成时,大屏会触发:
- 🏆 金色径向闪光 覆盖全屏
- 📜 50 片彩色纸屑 从天而降(带随机摆动)
- 💬 居中显示 "全部成绩已录入 · 本场次比赛完毕"
- ⏱️ 5 秒后自动消失
6.5 底部跑马灯
滚动播报最新成绩或管理员自定义的公告文案。右侧实时显示「已录 / 总人数」统计。
7. 完整比赛流程 #
下面以一场 30 人 30 秒单摇计数赛为例,演示从开赛到结束的完整操作流。
创建比赛 → 批量导入项目(如"30秒单摇")→ 批量导入组别(男子/女子 × 各年级)→ 批量导入 30 名运动员 → 至少新建 5 个场地 → 给每个场地分配运动员(3-8 人/场)→ 审核通过所有注册裁判员 → 把大屏调到目标比赛。
裁判员用手机/平板打开
judge.html,登录后在 Hub 中确认自己负责的场地 → 等待比赛开始。
每位裁判员按出场顺序逐个录入成绩 → 提交后实时同步到大屏 → 观众实时看到最新排名。管理员可在「成绩总览」实时查看进度。
当某场次所有运动员成绩录入完毕 → 大屏触发🏆庆祝特效 → 管理员切到下一场次 → 重复。
管理员进入「成绩总览」→「成绩统计表」标签 → 切换到「成绩统计表」视图 → 打印或导出 Excel → 装订成纸质证书/奖状。
8. 常见问题 FAQ #
Q1. 裁判员登录时一直显示"账号审核中"怎么办?
显示"账号审核中"说明该裁判员注册后尚未通过管理员审核。需要管理员在「裁判员管理」中找到该裁判员,点击「通过审核」按钮。审核通过后账号自动启用,裁判员即可登录。
Q2. 输入密码错误时只有通用错误,没有红色边框?
检查后端是否正确返回 errorCode: 'WRONG_PASSWORD'。如果后端没问题但前端没显示,尝试清除浏览器缓存(Ctrl+Shift+R 强制刷新)。
Q3. 成绩提交后大屏没有立即更新?
大屏使用 SSE 实时同步,裁判员提交后 < 300ms 推送到大屏。如出现延迟:
- 检查网络连接 — 断网时大屏会显示红色横幅提示
- SSE 连接断开后会自动重连,同时保留 30 秒版本号轮询作为 fallback
- 在管理员端点击「设为大屏」重新下发一次可强制刷新
Q4. 打印成绩统计表时没有边框?
如打印时没有边框,请使用 Chrome 浏览器,且在打印设置中将边距设为"默认"或"无"。
Q5. 多个裁判员同时录入同一运动员会冲突吗?
不会。系统在数据库层使用唯一约束 + 后写入覆盖原则。同一个运动员的规定赛 T1/T2/T3 来自不同裁判员,互不冲突;计数赛成绩以后提交者为准。花样赛各维度(难度/完成/创意)也由不同裁判独立打分,互不影响。
Q6. 大屏显示"暂无比赛"?
需要在管理员端「比赛管理」中找到目标比赛,点击「📺 设为大屏」按钮。每个时刻只能有一个比赛被设为大屏。
Q7. 小程序编译报错 "Cannot read property of undefined"?
通常是用了 ?. 或 ?? 这类 ES2020 语法。微信小程序编译器默认不支持,需要改写成传统写法:
// ❌ 不支持
const name = app.globalData.judgeInfo?.name
// ✅ 改写为
const info = app.globalData.judgeInfo || {}
const name = info.name
Q8. 如何重置管理员密码?
管理员密码通过 Cloudflare 环境变量 ADMIN_PASSWORD 配置。重置方法:登录 Cloudflare Dashboard → Pages → 你的项目 → Settings → Environment Variables → 修改 ADMIN_PASSWORD 的值 → 重新部署。
Q9. 裁判员登录失败 5 次被锁定了怎么办?
系统有登录失败锁定机制:密码错误 5 次自动锁定 5 分钟。解决方式:
- 等待 5 分钟后自动解锁
- 管理员在「审计日志」页面找到锁定记录,点击「解除锁定」手动解锁
Q10. 部署到 Cloudflare Pages 失败?
常见原因:wrangler.toml 中 database_id 没改成真实 ID。详见 DEPLOY.md。
Q11. 大屏可以连接投影仪吗?
可以。推荐用一台笔记本电脑连接投影仪 → 浏览器打开大屏 → F11 全屏 → 设置浏览器开机自启。系统对宽屏(1920×1080+)和超宽屏(21:9)都做了适配。
Q12. 批量导入运动员时,分组名称不匹配怎么处理?
预览阶段会将分组不匹配的行标红,并在分组列下方显示具体原因(如"分组不匹配:运动员所属分组[少年组]不在赛事组别中")。处理方式:
- 直接点「确认导入」— 系统自动跳过标红记录,仅导入有效数据
- 导入完成后在结果弹窗里点「📥 导出失败记录」— 下载含失败原因的 Excel,修正后再次导入
- 点「重新导入失败记录」— 失败记录自动回填到预览窗口,便于快速重试
先在「赛事组别」中配置好所有组别,再下载运动员 Excel 模板填写数据,并从组别列表中复制粘贴组别名称,确保完全一致。
Q12. 批量导入时提示"确认导入"按钮是灰色的?
这说明预览中所有记录都不符合分组要求(全部标红),没有可导入的有效数据。需要先修正 Excel 中的组别名称,重新上传文件。
Q13. 分组字段为空的运动员能导入吗?
可以。分组为空的运动员不触发分组校验,会直接导入。导入后可在运动员管理列表中手动编辑补充组别。
Q14. 裁判员提示"账号已在其他设备登录"怎么办?
系统采用严格单点登录机制——同一裁判员账号同一时间只能在一个设备上使用(不限 Web 或小程序)。出现此提示说明该账号已在其他设备登录。解决方式:
- 联系当前使用者退出登录,退出后其他设备即可正常登录
- 管理员也可以在「裁判员管理」中禁用再启用该裁判员,强制释放会话
Q15. 裁判员页面显示红色"网络已断开"横幅?
这是断网检测功能。当网络断开时,裁判端和管理端页面顶部会显示红色横幅提示。解决方式:
- 检查网络连接(Wi-Fi/移动数据)
- 网络恢复后横幅会自动消失,无需手动刷新
- 断网期间已录入的成绩会在网络恢复后自动同步
Q16. 成绩总览导出 Excel 时表头不对?
导出逻辑分为 4 个分支:
- 计数赛专用:7 列(只有成绩列,不含 T1/T2/T3)
- 规定赛专用:10 列(含 T1/T2/T3)
- 花样赛专用:13 列(含难度/完成/创意/规定扣分/主裁扣分/排名)
- 混合导出(全部/按场地):通用 7 列,每行根据 scoreType 自动显示正确类型和成绩格式
Q17. 批量导入/删除项目很慢?
批量导入预设项目和批量删除项目/组别都采用一次 HTTP 请求完成(使用 D1 batch 一次性执行所有 SQL),不再逐个调用 API。选 10 个项目导入或删除,只需 1 次网络请求。
• 先登录者不受影响,不会被挤下线
• 退出登录即可释放,无需等待超时
• Web 端和小程序端共享同一套登录限制
Q18. 审计日志怎么看?
管理员端侧边栏 → 「审计日志」菜单。页面包含:
- 统计卡片:成功操作数、失败操作数、被拒绝数
- 锁定账号列表:当前被锁定的账号,可手动解除锁定
- 日志列表:按用户类型、操作类型、时间段等 6 个维度筛选,点击单条可展开详情 JSON