体测这件事,累的从来不是让学生跑 1000 米,而是后面那一堆事:
我们学校没有专门的体测系统。买现成的要么很贵,要么得装服务器、联网部署——可现实是:体测是在操场上、在教室的旧电脑上、在没有网的机房里用的。
所以我的目标很明确,也很“土”:做一套能拷进 U 盘、双击就能打开、断网也能用的系统。
我用 WorkBuddy 把它做了出来。成品是一个 241 KB 的单文件 HTML,双击即用,零依赖、零安装、零联网,130 项端到端自动化测试全部通过。
下面是完整过程,包括它自己揪出来的 3 个真实 bug。

图 1:系统首页的学区总览看板,参测率、优良率、各班级均分一屏可见
这一步我认为是整件事成败的关键。很多人上来就说“帮我做个 XX 系统”,结果做出来的东西跑不起来、或者跑起来了但不符合实际场景。
我先把“立场”讲清楚,这是我实际发给它的第一段:
我要做一套《学生体质健康标准管理系统》,给我校(约 400 名学生、9 个年级)使用。
在动手写代码前,先记住三条硬约束,后面所有实现都必须满足:
约束一:单文件、纯离线。
学校电脑装不了运行环境,教室网络也不稳定。最终产物必须是一个 HTML 文件,
双击就能用浏览器打开,不依赖任何服务器、不引用任何外部 CDN 脚本或样式,
断网状态下所有功能都要正常。
约束二:数据不出本机。
涉及未成年学生信息,所有数据只保存在使用者自己电脑的浏览器本地存储里,
不上传任何服务器。同时要能一键导出备份、换电脑时能恢复。
约束三:不做假入口。
没实现的功能,界面上一个字都不许出现。宁可写“暂不支持”,
也不要放一个点了没反应的按钮。
先不要写代码。请你先复述这三条约束,并告诉我你打算怎么分步实现。它复述得很准确,还主动补了一条我没有明确要求、但确实该有的东西:权限要在数据查询层做过滤,而不是靠隐藏按钮。这一点后面救了命(见 Step 6)。
项目 | 说明 |
|---|---|
工具 | WorkBuddy 桌面端,工作模式选 Agent(你说我做) |
运行环境 | 本机 Node 22(只用于构建和跑测试;使用系统的人不需要装任何东西) |
输入资料 | 《国家学生体质健康标准(2014 年修订)》全部评分附表 |
产物 |
|
关于“输入资料”这一步,我是把国标附表的评分档位整理成文本,一次性作为参考交给它的。这一步必须做扎实——阈值错了,后面所有分数都是错的。
我的第一条实际提示词就跟界面无关:
先不要写任何界面。请先设计数据表结构,一共 4 张,按建立顺序输出:
1)年级班级表;2)学生档案表;3)体测项目库;4)体测成绩记录表。
每张表列出:字段名、类型、主键/外键、约束。
关键要求:体测成绩记录表里,一条记录由
「学生 + 测试学年 + 测试日期 + 项目」共同确定。
同一学生不同日期测试 → 必须新增一条历史记录,绝对不能覆盖旧数据。
只有学年、日期、项目完全相同,才视为对这一次记录的修正。
同时说明:为什么这种设计比“一个学生一行、每次覆盖”更好?它给出的第 4 张表设计正是我要的。这里我想强调这个设计有多重要:
体测一学年要测两次,家长和老师真正想看的是“这个孩子去年 4 分 50,今年 4 分 20”的进步。如果按“一行一个学生、每次覆盖”来存,趋势图就永远画不出来。这是一个很典型的“外行设计”,而我只需要在提示词里把业务讲清楚,它就不会走偏。
另外三张表上它还主动加了两个保护:
这两个我原本没提,是它加的,而且加得对。
请把《国家学生体质健康标准(2014年修订)》的评分数据单独做成一个数据文件,
不要和计算逻辑混在一起。分为:权重表(1-9年级分学段)、BMI 区间表(男女各年级)、
各单项评分表、附加分表。
另外实现一个筛选函数:itemsFor(年级, 性别),返回该学生适用的测试项目。
注意项目是随年级变化的,比如 1-2 年级没有仰卧起坐,7-9 年级才有立定跳远和耐力跑。这么做的收益是长期的:国标以后修订,只需要改数据文件,不用碰任何逻辑代码。
现在实现计算引擎,输出一个独立的 scoring 模块,包含以下能力:
1)自动算 BMI:体重 ÷ 身高²,保留 1 位小数,并按国标区间给分;
2)自动算单项得分:数值型项目「≥阈值即得分」,计时型项目「≤阈值即得分」,
从 100 分逐档向下匹配,低于最低档记 0 分;
3)自动判等次:优秀≥90、良好 80-89.9、及格 60-79.9、不及格<60,并给出配色;
4)自动算总分:标准分 = Σ(单项得分 × 权重);学年总分 = min(120, 标准分 + 附加分);
如果有缺测项目,标准分要按已测项目的权重折算,并且明确标注“缺测”;
5)自动识别短板:单项得分 <70 标记「重点加强锻炼」;
6)自动匹配锻炼建议:按「短板项目 + 学段」检索建议库。附加分这块它做得比我预期细,完全按国标来:小学跳绳每超 2 次加 1 分(上限 20 分);初中男生引体向上每超 1 次加 1 分、1000 米每少用 4 秒加 1 分(各上限 10 分);初中女生 800 米每少用 5 秒加 1 分。

图 2:成绩录入页,按「测试学年 / 测试日期 / 班级」筛选后逐生录入
现在做界面,一共 7 个页面,左侧导航切换:
① 学区总览看板 ② 体测预警清单 ③ 学生与班级 ④ 体测成绩录入
⑤ 体质报告单 ⑥ 权限与设置 ⑦ 使用说明
重点是成绩录入页,要求:
- 顶部先选「测试学年 / 测试日期 / 班级」;
- 学生一览表显示:适用项目数、本次已录、本次得分、本次等次、历史次数;
- 点「录入成绩」弹窗,一次性列出该生全部适用项目;
- 每个项目下方实时显示:原始成绩 → 单项得分 → 等次(配色)→ 附加分 → 本项目 100 分线;
- 身高体重录入后,BMI 自动填充且只读;
- 弹窗底部实时汇总:已录项目 / 标准分 / 附加分 / 学年总分 / 综合等级 / 缺测提醒。“输入即算分”是这个系统最实用的地方:老师一边录入,一边就看见这一项得多少分、离 100 分线差多少,不用等录完再算。

图 3:录入弹窗一次列出该生全部适用项目,输入原始成绩即实时算出得分与等次
请实现两块输出:
A. 学生体质报告单:基本信息 → 本次总评(标准分/附加分/总分/等级)→
单项成绩明细(权重、原始成绩、单项得分、等级、加权得分)→
历史成绩趋势折线图 → 薄弱项目与锻炼建议 → 三方签字栏。
要求点「打印 / 导出 PDF」时自动隐藏侧边栏和顶栏,按 A4 纵向排版。
B. 体测预警汇总清单:按学年/年级/班级/预警类型(全部、综合不及格、单项薄弱、缺测)筛选,
输出预警总览统计、预警项目排行、预警学生清单(按紧急程度排序、含预警原因),
并支持一键导出 Excel,包括一个「体育教师跟进表」(含干预措施、家庭练习要求、计划复测日期)。
图 4:学生体质报告单,含单项明细、历史趋势折线图与锻炼建议,可直接打印

图 5:体测预警清单,按「综合不及格 / 单项薄弱 / 缺测」筛选并支持一键导出
增加权限:两个角色。
- 学区校长:可查看全部班级与学生数据、全部报表;
- 体育教师:仅能查看和录入本人所带班级,其他班级数据不可见。
注意:权限必须在数据查询层统一过滤(比如 studentList / allRecords / canEditClass),
不能只靠隐藏按钮或置灰——按钮藏起来但接口还能查到数据,等于没有权限。
数据安全方面:数据存浏览器本地;支持一键导出 JSON 备份;支持覆盖恢复与按学号合并导入;
支持按学年归档数据快照。注意最后那句“不能只靠隐藏按钮”——这是我在第二段提示词里跟它确认过的事。很多同类系统就是靠 CSS 把按钮藏起来的,本质上没有权限。

图 6:权限与设置页,两种角色的权限在数据查询层统一过滤
这是我认为最值得学的一步。AI 写代码很快,但你怎么知道它写对了?
我的做法是:让它自己写一套端到端测试,而且必须是“真实点击”的那种,不是“看起来对”的那种。
最后两件事:
第一,把 src 下的全部源码合并内联成一个单文件 HTML,产出物必须双击可用、
不引用任何外部资源(构建脚本要检查并报告是否还有外链)。
第二,写一套端到端测试。要求通过 Chrome DevTools Protocol 真实驱动本机 Chrome,
以 file:// 协议打开成品页面,真实加载、真实点击、真实读写 localStorage,
而不是在 Node 里 mock 一遍。
至少覆盖:国标阈值抽查、自动计算(BMI/标准分/附加分/封顶/等级/缺测折算/趋势/短板)、
Excel 导入导出往返一致、四张表的增删改查、「不覆盖旧数据」、
备份恢复与合并去重、年度归档、两种角色的权限、7 个页面是否都能正常渲染、
真实点击流程(新增班级→新增学生→录成绩→自动算分)、刷新与关闭重开后的数据保留、
弹窗在 80%/90%/100% 缩放和小窗口下是否可用。
测试过程中请把关键页面截图保存下来。跑完的结果:
=== 测试结果汇总 ===
通过:130 项
失败:0 项测试覆盖 15 个板块,包括国标阈值抽查 36 项、自动计算 23 项、弹窗缩放适配 10 项、真实点击流程 8 项。
但真正让我信任这套系统的,是测试过程中它自己揪出来的 3 个 bug——这三个如果靠肉眼检查,我一个都发现不了:
缺陷 | 后果 | 修正 | |
|---|---|---|---|
1 | BMI(占 15% 权重)被排除在计分项目之外 | 初一男生的标准分被错误地按 85% 权重折算,全班分数整体偏低 | 已修复 |
2 | 初中男生引体向上评分表档位错位(国标不设 78/74/70/66/62 这五档) | “8 次”被算成 78 分,正确应为 76 分 | 按官方空档对位修复 |
3 | 成绩录入弹窗实时算分处报 | 输入成绩后预览区直接崩溃,看不到得分 | 已修复 |
第 1 和第 2 个都是算错分但不报错的类型——页面照常显示,数字看起来也“像那么回事”,只有写测试去复算才会暴露。这也是我最想分享的一条经验:
让 AI 写代码,就要让 AI 写测试。而且要写“真实点击”的测试,不能是“看起来对”的测试。
我的验收标准是这 5 条,全部满足才算做完:
坑 1:弹窗在小窗口/缩放下,保存按钮会跑到屏幕外。
一开始弹窗内容一多,底部的“保存”按钮就看不见了,老师录到一半没法保存。解决办法是弹窗用 flex 纵向布局 + max-height:94vh,内容区 overflow-y:auto,底部按钮区固定不滚动。这才做到任何缩放下按钮都常驻可见(测试里专门测了 80% / 90% / 100% 和 1024×620 小窗口)。
坑 2:单文件里出现 </script> 或 <!--,整个页面会直接炸。
所有代码内联进一个 HTML 之后,源码里只要有一处 </script,后面的内容就全被当成 HTML 解析了。所以构建脚本必须做危险序列检查和转义。
坑 3:断网也要能导入导出 Excel。
这是“约束一”直接逼出来的结果——不能引 CDN,就没有现成的表格库可用。最后是自己实现了 ZIP 打包(STORED + CRC32)和解包(解析中央目录,deflate 用浏览器原生的 DecompressionStream('deflate-raw'))。好处是:这个系统的 Excel 功能在完全断网的机房里照样能用。
坑 4:别用“看起来对”验收。
这是我踩的最大的坑。中期版本我肉眼扫了一遍界面,觉得没问题;写了真实点击测试才发现录入弹窗是崩的。
坑 5:没做完的功能要如实标注。
我一开始想让它“先给个入口,以后再实现”。后来还是按“约束三”改掉了——界面上不出现任何假入口。
指标 | 数值 |
|---|---|
产物 | 单个 HTML 文件,241 KB,13 个脚本块,零外部依赖 |
覆盖范围 | 小学一年级 ~ 初中三年级(1-9 年级),13 个测试项目 + 身高体重 |
页面 | 7 个(看板 / 预警 / 学生班级 / 成绩录入 / 报告单 / 权限设置 / 使用说明) |
自动化测试 | 130 项通过,0 失败 |
使用门槛 | 双击打开。不需要安装、不需要联网、不需要服务器 |
示例数据下的看板效果:40 名学生 / 4 个班级,参测率 100%,平均总分 79.3(满分 120),优秀 8 人、良好 11 人、及格 13 人、不及格 8 人——不及格比例 20%,一眼就看出该往哪个方向使劲。
关于数据脱敏。 本文所有截图中的学校名称已替换为「某中学」,学生姓名已打码为「郑**」形式,截图内的班级和学生数据为系统内置的示例数据,不是真实师生信息。这一点我建议所有做教育类系统的同行都当成默认动作——先脱敏,再展示。
关于未实现的功能。 以下几项这个系统没有做,界面上也没有任何假装已实现的入口:
目前这些环节需要手工录入或使用 Excel 批量导入。后续如果要做,可以从数据层的 addStudent / importBackup 两个入口接入。
三句话概括这次的经验:
这套思路完全可以平移到别的场景:心理健康档案、社团选课、考勤统计、题库管理,本质都是“本地数据 + 国标规则 + 统计报表 + 打印输出”。
如果你也在学校或者行政岗位,欢迎在评论区聊聊你被哪个 Excel 折磨过,我可以继续把这套做法整理成可直接套用的模板。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。