纯前端体测管理系统源码包拆解与改造指南
简介这是一套面向高校计算机专业学生与初学者的体测管理系统Web前端源码采用学生端与教师端双视角设计覆盖身高、体重、50米跑、立定跳远、引体向上、1000米等多个常见体测项目的数据录入与汇总管理可作为课程设计或期末大作业的完整交付方案。压缩包共37个文件、总大小13.47MB以17个HTML页面为主体串联登录注册、学生体测操作、教师预览与数据展示等核心流程并搭配4个CSS样式表与3个JS脚本含jQuery库实现页面布局和交互逻辑另有字体图标、图片及JSON数据文件补充前端资源整体目录结构清晰便于按模块查找与二次开发。已有560人学习。开发者可从中获取一套能直接运行的前端项目骨架多页面跳转组织方式、基于Bootstrap的响应式布局、体测项目模块的UI划分思路随包另附项目说明文档和数据表文件能快速理解功能模块与数据表结构的设计逻辑为期末大作业或毕业设计预研提供实用参考。1. 大学生体测管理系统纯前端源码包也能撑起完整演示流程“大学生体测管理系统”这个名字听起来像是要搭后端、连数据库的大工程但实际拆开这个源码包会发现整套系统完全跑在浏览器本地打开登录页录入身高、体重、50米、跳远、1000米等体测数据切到教师端还能预览汇总结果全程没有一行后端代码靠 HTML、CSS、Bootstrap 和 jQuery 就串起了完整流程。很多同学把它当作期末大作业提交演示时从登录跑到教师预览节奏顺滑。适合两类人一类是数据库课还没结、却要交一个能现场跑通的系统另一类是刚学完前端基础想看看别人怎么把十几个页面组织成一个可用应用。下面我从文件骨架、数据存储、运行调试到踩坑和改造把这套源码彻底拆一遍。2. 从解压目录到页面跳转看懂这套系统的文件骨架与登录逻辑拿到压缩包的第一步不是双击页面而是先整理目录。这套系统的文件命名很直白几乎每个 HTML 都对应一个功能页面资源文件按类型放在独立目录里。搞清楚哪些是页面、哪些是依赖、哪些是数据后面改起来才不会抓瞎。2.1 文件分类三张表页面、资源、数据各归其位先按用途把文件分成四类每类看一眼就知道它在这个系统里扮演什么角色。分类典型文件在系统里的作用登录与入口页logIn.html、register.html、index.html、星空图.html学生登录、注册、首页过渡与装饰展示体测项目页P.Etest.html、50m.html、jump.html、weight.html、1000m.html、height.html、ztqq.html、ytxs.html、cogg.html、vision.html主测试台与各项目成绩录入页教师端页面teacherLogIn.html、teacherPreview.html教师登录与成绩预览汇总样式与脚本css/bootstrap.css、P.Etest.css、js/jQuery.min.js、js/mouse.js布局样式、UI 框架与交互逻辑字体与图标font/iconfont.ttf、iconfont.css、iconfont.js、iconfont.woff、iconfont.woff2、iconfont.json页面里的矢量小图标图片素材images/.jpg、.png页面背景与展示图数据数据表存放体测成绩的表格文件通常可用 Excel 打开P.Etest.html 是整套系统的核心它承载了主测试台的角色。打开这个文件能看到六个体测项目的入口卡片分别链到 50m.html、jump.html、weight.html、1000m.html、height.html、ztqq.html其中 ztqq 对应坐位体前屈ytxs 对应仰卧起坐cogg 对应引体向上vision.html 是视力测试页。每个项目页独立成文件好处是改某个项目的 UI 不会影响其他页面坏处是成绩如果只存在各自页面里跨页共享就要借助浏览器存储来做。图片素材里那两张 unsplash 风格的照片大概率是登录页和主控台的背景图如果你要提交课程设计把这两张换成校园实拍或截图会更“像自己做的”。这部分改动成本很低后面我会专门讲怎么换。2.2 登录与注册入口学生端和教师端的分流设计先梳理登录链路。入口页面是 logIn.html注册页 register.html 负责收集学生姓名和学号。教师端单独走 teacherLogIn.html成功后进 teacherPreview.html。这个设计把两类用户彻底分开了学生登录后进主测试台教师登录后进预览页。分工明确演示的时候也好讲先让学生录入再切教师账号看汇总。纯前端实现登录没有真实的账号校验常见的做法是把账号密码写在前端 JS 里判断或用本地存储存一条注册记录。我一般会在 logIn.html 里看到类似这样的逻辑// logIn.html 中的登录分流处理 $(#loginBtn).on(click, function () { var role $(#role).val(); // 下拉框选择学生或教师 var username $(#username).val().trim(); var password $(#password).val().trim(); if (!username || !password) { alert(用户名和密码不能为空); return; } // 教师端固定演示账号学生端允许任意非空账号进入 if (role teacher) { if (username admin password 123456) { window.location.href teacherPreview.html; } else { alert(教师账号或密码错误); } } else { window.location.href P.Etest.html; } });这段代码用 jQuery 绑定了登录按钮的点击事件根据下拉框里的角色值走不同分支。注意两个细节第一个是判断用户名单选后再走流程避免空值直接跳转第二个是教师端的账号密码硬编码在 JS 里这是纯前端项目最常见的写法好处是演示时不用配数据库坏处是任何人打开控制台都能看到密码。实际交付课程设计时如果答辩老师问起安全问题可以如实回答这是演示用逻辑真实系统应该在服务端校验。注册页 register.html 的逻辑更简单把学号和姓名写入 localStorage然后跳回登录页。关键在于写入键名的规则后面做数据聚合时会用到。2.3 主测试台到项目页跳转链与返回机制P.Etest.html 作为主测试台它的 HTML 结构里通常是一张卡片网格每张卡片是一个a链接指向对应的项目页。项目页录入完成后浏览器返回按钮可以退回主测试台但更稳妥的做法是每个项目页提供一个“返回主测试台”按钮用 location.href 指回 P.Etest.html。// 项目页通用的返回逻辑先记录当前项目名再回主控台 function goBack(project) { sessionStorage.setItem(lastProject, project); window.location.href P.Etest.html; }这里用 sessionStorage 而不是 localStorage 记录“从哪个项目回来”是个很实用的细节。sessionStorage 在标签页关闭后自动清空不会留下历史痕迹适合存这种临时导航状态。主测试台如果要做“上次测试项目”的提示读取这个键就行$(function () { var last sessionStorage.getItem(lastProject); if (last) { $(#tip).text(上次录入项目 last); } });这套跳转链设计得很朴素但足够撑起课程设计的演示需求。项目页之间不互相跳转全部从主测试台进出路径清晰也避免了页面间状态传递的复杂度。3. 成绩存哪、字段怎么定数据表结构与前端存储方案拆解体测系统最核心的问题是成绩怎么存。这套源码里有两套存储一份是压缩包里的“数据表”文件另一份是浏览器自己的 localStorage。两套体系分别对应两种使用场景搞清楚它们的结构和关系才能真正读懂这套系统。3.1 数据表文件里有什么核心字段与记录格式压缩包根目录下的“数据表”一般是一份 Excel 或 CSV 格式的成绩登记表字段设计基本遵循高校体测的常用指标。按常见实现推断它的列结构大致如下字段名类型说明学号 student_id文本学生唯一标识姓名 student_name文本学生姓名性别 gender文本男 / 女身高 height_cm数值单位厘米体重 weight_kg数值单位千克50米跑 run_50m数值单位秒立定跳远 jump_cm数值单位厘米1000米跑 run_1000m数值单位秒坐位体前屈 sit_reach数值单位厘米仰卧起坐 sit_up数值单位次数引体向上 pull_up数值单位次数左眼视力 vision_left数值视力值测试日期 test_date日期本次体测时间这份数据表有两个作用一是作为文档交付给老师看证明数据模型设计过二是演示时把表格里的数据手工录入系统。它并不参与页面运行属于“静态数据支撑”。如果你要提交课程设计把这份表的数据填上十几条真实的模拟记录会在答辩时加分不少。3.2 localStorage 存成绩键名设计与读写实现运行时的成绩录入走的是 localStorage。每个项目页录入成绩后把数据写到以项目名和学生标识组合的键里。这套键名设计决定了后续能不能把成绩聚合起来我通常建议用统一的命名规则例如PE_项目_学号。// 保存一条体测成绩到 localStorage function saveScore(studentId, project, score) { var key PE_ project _ studentId; var record { studentId: studentId, project: project, score: score, updatedAt: new Date().toISOString() // ISO 格式时间便于排序 }; localStorage.setItem(key, JSON.stringify(record)); return record; } // 读取某个学生某个项目的成绩 function loadScore(studentId, project) { var key PE_ project _ studentId; var raw localStorage.getItem(key); return raw ? JSON.parse(raw) : null; }说明一下两个参数updatedAt存的是 ISO 格式时间字符串比时间戳更适合直接展示转成本地时间用new Date(record.updatedAt)即可score字段统一按字符串存方便在表格里原样显示需要计算时再parseFloat。这样设计的好处是键名可枚举教师预览页能通过遍历localStorage里所有PE_开头的键把所有成绩捞出来。3.3 扩展思路把前端存储替换成真实数据库如果答辩老师问“这套系统怎么接数据库”你不能只回答“我用 localStorage”。哪怕不实际写后端也要能说清楚思路。常见做法是把 localStorage 的读写函数替换成 AJAX 请求后端接口接收同样的字段。数据表里的列结构可以直接当作数据库表结构来用我一般会给出这样的建表参考CREATE TABLE physical_test ( id INT PRIMARY KEY AUTO_INCREMENT, student_id VARCHAR(20) NOT NULL, student_name VARCHAR(50) NOT NULL, gender TINYINT COMMENT 1男 2女, height_cm DECIMAL(5,1), weight_kg DECIMAL(5,1), run_50m DECIMAL(4,2), jump_cm DECIMAL(5,1), run_1000m INT COMMENT 秒, sit_reach DECIMAL(4,1), sit_up INT, pull_up INT, vision_left VARCHAR(10), test_date DATE, UNIQUE KEY uk_student_date (student_id, test_date) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;建表时最值得注意的是一行学生一天只能有一条体测记录用UNIQUE KEY uk_student_date约束。这是真实系统中容易漏掉的细节答辩时主动提一句老师会觉得你考虑过数据完整性。前端换成 AJAX 时只需要把saveScore里的localStorage.setItem换成$.post(/api/save, record)把loadScore换成$.get(/api/score?studentIdxxxprojectyyy)其余逻辑几乎不动。这也是这套源码最有价值的地方数据访问层被集中封装在几个函数里替换成本低。4. 把源码跑起来的完整流程启动顺序、JS 初始化和参数调整这个源码包有一个隐蔽的启动要求不要直接双击 HTML 文件打开否则部分浏览器会限制本地存储和字体加载。正确的跑法是用本地服务器方式启动下面把完整流程和需要调整的参数走一遍。4.1 解压与启动目录完整性和入口页选择先确认解压后的目录结构完整。最容易出的问题是解压时选择了“解压到当前文件夹”导致 css、js、font 目录被嵌套了一层页面找不到样式。正确操作是在压缩包上解压到独立文件夹然后检查根目录下能看到css/、js/、font/、images/这些目录与 HTML 文件平级。启动推荐用 Python 自带的 HTTP 服务几秒就能起来cd /path/to/解压后的目录 python -m http.server 8080然后用浏览器打开http://localhost:8080/logIn.html。为什么不直接双击因为 localStorage 是绑定协议和域名的在file://协议下部分浏览器尤其是旧版 Chrome会拒绝写入表现为成绩录完刷新就没了。换成http://localhost后localStorage 的读写就完全正常iconfont 字体也会从本地服务正常加载。这一步是整套源码能稳定运行的大前提。4.2 核心 JS 初始化顺序jQuery、mouse.js 与样式表页面要正常工作依赖加载顺序必须正确。这套系统的每个 HTML 页面几乎都依赖 jQuery部分页面还用了 mouse.js 做鼠标特效。正确的引用顺序如下!-- 先引用样式 -- link relstylesheet hrefcss/bootstrap.css link relstylesheet hreffont/iconfont.css link relstylesheet hrefP.Etest.css !-- 再引用脚本jQuery 必须在自定义脚本之前 -- script srcjs/jquery.min.js/script script srcjs/mouse.js/script !-- 页面自带的内联脚本或外部脚本最后加载 -- script srcjs/main.js/script顺序错乱会引发两类典型问题一是样式不生效因为 Bootstrap 样式被后面的自定义样式覆盖布局变乱二是$ is not defined因为页面内联脚本执行时 jQuery 还没加载。mouse.js 这个文件的作用通常是给页面加鼠标跟随或点击特效如果它在 jQuery 之后加载却报错要看它内部是否调用了$函数确认依赖关系。初始化时的参数主要在页面顶部打开任意一个项目页通常能找到类似下面的配置区// 页面顶部可调整的识别参数 var CONFIG { studentId: 20240001, // 默认学号可改成当前登录学生 project: 50m, // 当前项目名对应数据表列名 unit: 秒, // 成绩单位跳远是厘米体重是千克 minValue: 0, maxValue: 60 // 50米跑合理范围超出提示重新输入 };这些参数直接决定了成绩录入的校验范围。比如 50 米跑男生合理成绩在 6 秒到 20 秒之间把maxValue设成 60 是为了兼容女生和体测免测的宽松录入。如果你要改成身高项目把unit换成“厘米”、maxValue设成 220 就行。参数化设计的思路值得保留项目页之间只换配置不换逻辑。4.3 教师预览页与附加页面演示时怎么用teacherPreview.html 是整包源码里功能最接近“后台管理”的页面。它通过遍历 localStorage 里全部PE_开头的键按学号聚合后渲染成表格类似这样function renderTeacherTable() { var keys Object.keys(localStorage).filter(function (k) { return k.indexOf(PE_) 0; }); var rows {}; keys.forEach(function (key) { var record JSON.parse(localStorage.getItem(key)); if (!rows[record.studentId]) { rows[record.studentId] { studentId: record.studentId }; } rows[record.studentId][record.project] record.score; }); // rows 已经按学号聚合直接渲染到 table 即可 console.table(rows); }注意这段代码用console.table输出只是为了调试实际演示时要把数据拼成 HTML 表格再插入页面。教师预览页的数据来自浏览器存储所以演示顺序必须是先登录学生端录入成绩再打开教师端预览。如果先打开教师端表格就是空的会显得系统“没数据”。附加页面里的“星空图.html”是一个纯装饰页面一般放在登录页之前做过渡动画演示时点一下展示氛围即可它不参与业务逻辑。5. 避坑记录这套体测系统最容易翻车的五个问题这套源码被人问得最多的不是功能不够而是“为什么我打开和教程不一样”。以下五个坑是我在实际拆解时反复遇到的按现象、原因、解决的顺序写清楚。5.1 画面白屏或样式全乱现象双击 index.html 或 logIn.html 后页面纯白控制台报错Failed to load resource或者页面没有样式文字从上往下堆成一竖列。原因绝大多数是目录结构被破坏。解压工具把内层文件夹又包了一层css/bootstrap.css在二级目录里页面用相对路径css/bootstrap.css找不到文件。另一个常见原因是直接双击 HTML 使用file://协议访问浏览器拦截了本地子资源加载。解决先检查 HTML 文件与css、js、font目录是否平级。然后放弃双击改用我在 4.1 里写的python -m http.server方式访问。这两个动作能解决九成白屏问题。5.2 刷新页面后已录成绩全部消失现象在项目页录入成绩点返回再进入成绩还在一刷新页面表格空了或者切换教师端后一条记录都没有。原因写入和读取 localStorage 的键名不一致。有的页面保存时用PE_50m_20240001读取时却写成了PE_50m_20240001以外的拼接方式比如把项目名放在前面或者多拼了一个下划线。还有一种是浏览器对file://协议下的 localStorage 做了隔离刷新后直接拿不到。解决先把所有页面里的saveScore和loadScore函数统一成同一套键名规则。其次强制用http://localhost访问。判断是不是键名问题在浏览器控制台执行Object.keys(localStorage)把全部键打出来人眼比对一下能否对应上。5.3 iconfont 图标显示成方块现象页面上应该出现的剪刀、小人、刷新等小图标全部变成了一个个空心方块占位但内容错误。原因iconfont 的样式文件font/iconfont.css虽然被引用了但字体文件路径不对。HTML 在student/子目录时CSS 里写的font/iconfont.ttf相对路径指到了错误位置导致字体资源 404浏览器只能用系统缺省字形渲染。解决检查所有页面前提是图标必须和 CSS 同源访问。推荐把iconfont.css里的src: url(iconfont.woff2)改成相对 CSS 文件的路径例如url(../font/iconfont.woff2)。更省事的办法是保证所有页面都放在根目录不要放进子目录。5.4 控制台报错$ is not defined现象打开项目页后页面元素都在但没有任何交互按钮点了没反应控制台红色报错Uncaught ReferenceError: $ is not defined。原因jQuery 没有被加载或者加载顺序晚于页面内联脚本。打开浏览器开发者工具的 Network 标签能看到jQuery.min.js这一行是红色 404 或者加载顺序靠后。解决把script srcjs/jquery.min.js/script移到所有自定义脚本之前。同时检查 jQuery 文件本身是否存在有的压缩包因为压缩工具的问题会把文件名多一个空格或后缀jQuery.min.js变成了jQuery.min.js (1)复制代码时引入路径必然 404。5.5 数据表用 Excel 打开中文乱码现象解压出的“数据表”文件用 Excel 打开后学号姓名全是乱码但用记事本打开却能正常显示中文。原因文件实际编码是 UTF-8而旧版 Excel 默认按 GBK 解析无 BOM 的 UTF-8 文件导致中文错乱。这类数据表文件多为工程人员在非 Windows 环境导出的比较常见。解决用记事本打开文件另存为时编码选“带 BOM 的 UTF-8”再用 Excel 打开就正常了。如果你用的是 WPS直接在打开对话框里选“UTF-8 编码”也能解决。顺带一个习惯拿到任何数据表先右键用记事本看前两行确认编码再交给 Excel能少踩很多坑。6. 让课程设计显得更完整演示动线设计、换肤与数据表加字段6.1 两分钟演示动线演示这门课设不要按开发顺序讲按业务顺序走评委更容易跟上。我的习惯动线是先打开“星空图.html”停在进入页一秒点进登录页学生端注册一个演示账号进入主测试台依次在身高、体重、50米、跳远四个项目页录入四组数据返回主测试台退出登录切到教师端输入演示账号进预览页展示聚合后的表格。这一套下来录入了、查到了、角色分开了评估点全覆盖。6.2 低成本改造清单给这套源码“换皮”是最划算的改造。改动三处即可让页面看起来和原版明显不同第一处是 HTML 里的title标签改成自己学校的课程设计题目第二处是登录页背景图把 images 目录里的 unsplash 图替换成截图或自制 banner注意保持 JPG 格式和原文件名第三处是 P.Etest.css 里的主色调全局搜索#409EFF这类色值替换成红色或绿色UI 风格立刻变化。改完用 5.1 的方式跑一遍确认样式没被引错。6.3 提交前强制走一遍的五项检查每次提交前我都强制自己按这张清单走一遍第一清空浏览器全部站点数据后重新录入完整的五条学生成绩教师端能正确聚合。第二换一台电脑或换一个浏览器打开确认不依赖特定环境。第三把“数据表”用 Excel 重新打开检查编码和中文字段。第四随机点开三个项目页确认返回按钮都能回到主测试台。第五把 jQuery 引用路径从相对路径改成能通行的根路径。这套检查能过滤掉绝大多数会被答辩现场暴露的问题。这套源码让我想起自己第一次拿到别人写的期末项目时的状态页面打开一片乱折腾半小时发现只是启动方式不对。从那以后我每次拿到陌生前端源码包都强制先起本地服务器、再看目录结构、最后才打开页面这套顺序帮我少走了很多弯路。希望帮到你。本文还有配套的精品资源点击获取