首页
/
行业洞察
/
正文
INDUSTRY INSIGHT · 深度
SpringBoot+Vue学生考勤系统源码:从环境搭建到二次开发全攻略
📅 2026/10/7 16:53:30
✍️ 爱科研究院
👁 阅读 3,247
简介这是一套面向计算机相关专业毕业设计与课程设计场景的学生考勤管理系统完整项目包采用SpringBoot后端与Vue前端分离架构以MySQL作为数据库适合正在准备毕设的Java学习者以及需要项目实战练习的开发者直接参考或二次开发。压缩包共428个文件约69.47MB其中107个java文件承载后端业务逻辑43个vue文件构建前端页面另有xml、yml、properties等配置文件和sql数据库脚本以及docx开发说明文档、答辩PPT、演示视频与代码注释覆盖从环境搭建到功能演示的完整链路。系统按管理员、教师、学生三类角色划分模块包含学生管理、班级与课程信息管理、签到与考勤信息管理、请假信息管理及考勤统计等功能业务闭环清晰便于理解权限控制与数据统计的实现思路。目前已有677人学习下载可作为高分毕设参考帮助读者快速掌握项目结构、排错方法与答辩要点。1. 从一份能跑起来的考勤系统源码说起它到底解决了什么问题很多同学做毕业设计时最头疼的不是写不出代码而是拼不出一套能演示、能答辩、能交差的完整系统。这份基于 SpringBoot Vue 的学生考勤管理系统源码包恰好卡在这个痛点上——它不是零散的功能片段而是一套前后端分离、带数据库脚本、带配套文档的可运行工程。后端用 SpringBoot 提供 REST 接口前端用 Vue 做页面交互数据库落 MySQL覆盖学生信息管理、课程考勤记录、请假审批、统计报表这几条主线。适合谁正在做课程设计或毕业设计、需要一套结构清晰可二次开发的参考项目的人也适合刚接触前后端分离、想找一个真实业务场景练手的初学者。它解决的核心问题是把「考勤」这个具体业务从需求到落地的全链路跑通让你拿到手就能启动、能改、能讲清楚每一层在干什么。2. 环境准备与工程结构先把 SpringBoot 和 Vue 的依赖理顺2.1 后端技术栈与版本选择这套工程后端基于 SpringBoot 框架配合 MyBatis 做持久层MySQL 存数据。常见做法是把 SpringBoot 版本控制在 2.7.x 这一档原因很实际2.7 是 2.x 的最后一个稳定分支对 JDK 8 和 JDK 11 都友好网上资料多遇到问题好搜。如果你本地装的是 JDK 17SpringBoot 3.x 也能跑但要注意 3.x 把 javax 包换成了 jakarta老代码里的javax.servlet相关引用会直接编译不过这就是热词里「springboot版本太高」的典型翻车现场。选版本时我一般会先确认三件事JDK 版本、MySQL 版本、Maven 版本。JDK 8 配 SpringBoot 2.7 是最省心的组合MySQL 用 5.7 或 8.0 都行但 8.0 的驱动类名和连接串参数跟 5.7 有区别下面会讲。Maven 用 3.6 以上即可。后端目录结构大致是这样src/main/java/com/example/attendance/ ├── controller/ // 接口层接收前端请求 ├── service/ // 业务逻辑层 ├── mapper/ // MyBatis 映射接口 ├── entity/ // 数据库实体类 └── config/ // 跨域、拦截器等配置 src/main/resources/ ├── application.yml // 数据源、端口等配置 └── mapper/ // XML 映射文件这个分层不是摆设。controller 只负责参数校验和返回service 写业务规则比如「同一学生同一节课不能重复签到」mapper 管 SQL。改需求时你清楚该动哪一层不会牵一发动全身。2.2 前端 Vue 工程与依赖安装前端是 Vue 单页应用用 Vue CLI 或 Vite 搭建都行。热词里「vue安装及环境配置」「vue安装依赖」是高频问题这里说清楚先装 Node.js建议 16.x 或 18.x LTS 版本然后全局装包管理器。# 确认 node 和 npm 版本 node -v npm -v # 进入前端目录安装依赖 cd attendance-frontend npm install # 启动开发服务器 npm run servenpm install这一步最容易卡住原因通常是网络拉包慢或某个依赖版本冲突。如果卡在某个包上先删掉node_modules和package-lock.json重来别硬等。启动后默认跑在 8080 端口如果跟后端端口撞了改vue.config.js里的devServer.port。前端跟后端联调靠的是接口地址配置。一般在src/utils/request.js里配 axios 的baseURL指向后端服务地址比如http://localhost:9090。这里有个细节后端端口别用 8080跟前端错开否则两个服务抢端口启动时报「端口被占用」新手容易懵。2.3 数据库脚本导入与连接配置数据库是这套系统的地基。源码包里通常带一个.sql文件导入方式# 登录 MySQL mysql -u root -p # 创建数据库 CREATE DATABASE attendance_db DEFAULT CHARACTER SET utf8mb4; # 导入脚本 use attendance_db; source /path/to/attendance.sql;导入后检查表是否齐全一般会有学生表、课程表、考勤记录表、用户表这几张。然后改后端application.yml的数据源配置spring: datasource: url: jdbc:mysql://localhost:3306/attendance_db?useUnicodetruecharacterEncodingutf8serverTimezoneAsia/Shanghai username: root password: 你的密码 driver-class-name: com.mysql.cj.jdbc.Driver注意driver-class-nameMySQL 8.0 用com.mysql.cj.jdbc.Driver5.7 用com.mysql.jdbc.Driver。写错了启动就报「Cannot load driver class」这是血泪经验里排第一的坑。serverTimezone参数在 8.0 驱动下必须加否则连接时报时区错误。3. 核心功能模块拆解考勤记录、请假审批与统计报表怎么落地3.1 考勤签到接口的实现逻辑考勤系统的核心是「签到」这个动作。后端一般提供一个 POST 接口前端传学生 ID、课程 ID、签到时间后端校验后写库。看一段典型的 controller 代码RestController RequestMapping(/api/attendance) public class AttendanceController { Autowired private AttendanceService attendanceService; // 学生签到接口 PostMapping(/checkin) public Result checkin(RequestBody CheckinDTO dto) { // 校验该学生是否已签到避免重复 boolean exists attendanceService.isCheckedIn(dto.getStudentId(), dto.getCourseId()); if (exists) { return Result.fail(本节课已签到请勿重复操作); } attendanceService.saveRecord(dto); return Result.success(签到成功); } }这段逻辑的关键在isCheckedIn这个校验。没有它学生连点两次按钮就产生两条记录统计就乱了。CheckinDTO是数据传输对象只装前端传来的字段不直接暴露实体类这是常见做法能避免前端传多余字段污染数据库。service 层写业务规则比如判断签到时间是否在课程有效时间段内public void saveRecord(CheckinDTO dto) { // 查询课程信息拿到上课时间段 Course course courseMapper.selectById(dto.getCourseId()); LocalTime now LocalTime.now(); if (now.isBefore(course.getStartTime()) || now.isAfter(course.getEndTime())) { throw new BusinessException(不在签到时间段内); } Attendance record new Attendance(); record.setStudentId(dto.getStudentId()); record.setCourseId(dto.getCourseId()); record.setCheckinTime(LocalDateTime.now()); record.setStatus(正常); attendanceMapper.insert(record); }参数说明startTime和endTime存在课程表里格式用TIME类型。BusinessException是自定义异常配合全局异常处理器返回统一错误格式前端好解析。3.2 请假审批的状态流转请假审批是个典型的状态机学生提交 → 待审批 → 教师审批 → 通过或驳回。数据库里请假表要有一个status字段用数字或字符串表示状态。常见做法是用枚举public enum LeaveStatus { PENDING(待审批), APPROVED(已通过), REJECTED(已驳回); private final String desc; LeaveStatus(String desc) { this.desc desc; } public String getDesc() { return desc; } }审批接口接收请假 ID 和审批结果更新状态PostMapping(/leave/approve) public Result approve(RequestBody ApproveDTO dto) { Leave leave leaveService.getById(dto.getLeaveId()); if (!LeaveStatus.PENDING.getDesc().equals(leave.getStatus())) { return Result.fail(该申请已处理不能重复审批); } leave.setStatus(dto.getApproved() ? LeaveStatus.APPROVED.getDesc() : LeaveStatus.REJECTED.getDesc()); leave.setApproveTime(LocalDateTime.now()); leaveService.updateById(leave); return Result.success(审批完成); }这里的状态校验是防重复审批的关键。没有它教师误点两次状态就被覆盖了。审批通过后通常还要联动考勤记录——把对应课程的考勤状态改成「请假」这一步在 service 里用事务包起来保证请假状态和考勤记录同时更新要么都成功要么都回滚。3.3 统计报表的 SQL 聚合写法统计报表是答辩时的加分项。常见需求按课程统计出勤率、按学生统计缺勤次数。这类查询用 SQL 聚合函数直接搞定别在 Java 里循环算数据量一大就慢。-- 按课程统计出勤率 SELECT c.course_name, COUNT(a.id) AS total, SUM(CASE WHEN a.status 正常 THEN 1 ELSE 0 END) AS normal_count, ROUND(SUM(CASE WHEN a.status 正常 THEN 1 ELSE 0 END) / COUNT(a.id) * 100, 2) AS rate FROM attendance a JOIN course c ON a.course_id c.id GROUP BY c.course_name;CASE WHEN是条件计数的标准写法ROUND保留两位小数。如果考勤表数据量大记得在course_id和student_id上建索引否则 GROUP BY 会全表扫描。前端拿到这个结果用 ECharts 画个柱状图或饼图答辩演示效果直接拉满。4. 前后端联调与打包部署从本地跑通到放进 SpringBoot4.1 跨域问题的三种解法前后端分离开发时前端 8080、后端 9090浏览器同源策略会拦请求报 CORS 错误。这是新手必踩的坑。解法有三种按场景选第一种后端加跨域配置最省事Configuration public class CorsConfig implements WebMvcConfigurer { Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping(/**) .allowedOriginPatterns(*) .allowedMethods(GET, POST, PUT, DELETE) .allowCredentials(true) .maxAge(3600); } }第二种前端配代理开发环境用// vue.config.js module.exports { devServer: { proxy: { /api: { target: http://localhost:9090, changeOrigin: true } } } }第三种Nginx 反向代理生产环境用。开发阶段用前两种就行别一上来就折腾 Nginx。4.2 Vue 打包放进 SpringBoot 的正确姿势热词里「vue打包放进springboot中」是个高频需求很多人想把前后端打成一个 jar 包部署。步骤是先npm run build生成dist目录再把dist里的文件拷到 SpringBoot 的src/main/resources/static下然后配一个转发规则让非接口请求都指向index.html。Controller public class IndexController { // 匹配非 /api 开头的路径转发到前端首页 RequestMapping(value /{path:[^\\.]*}) public String forward() { return forward:/index.html; } }这个正则[^\\.]*的意思是「不包含点的路径」避免把.js、.css这类静态资源也转发走。配好后打包成 jarjava -jar一跑前后端就都在一个端口了。注意 Vue 路由要用 history 模式才需要这个转发hash 模式带 #不用。4.3 打包命令与启动验证后端打包# 跳过测试打包加快速度 mvn clean package -DskipTests # 启动 java -jar target/attendance-0.0.1-SNAPSHOT.jar启动后看日志有没有报错重点看数据源连接和端口监听。浏览器访问http://localhost:9090能出登录页就说明前后端都通了。登录后走一遍签到、请假、看报表的流程确认核心功能正常。这一步别偷懒答辩前一定要完整走一遍我见过太多「本地能跑、换台机器就崩」的情况多半是数据库没导或配置没改。5. 避坑与排查那些让项目跑不起来的常见问题5.1 启动报「Cannot load driver class」现象SpringBoot 启动直接失败日志里一行Cannot load driver class: com.mysql.jdbc.Driver。原因MySQL 驱动版本和驱动类名不匹配。8.0 的驱动包已经移除了com.mysql.jdbc.Driver只剩com.mysql.cj.jdbc.Driver。解决改application.yml里的driver-class-name同时确认pom.xml里 mysql-connector 的版本跟本地 MySQL 对得上。8.0 数据库配 8.0 驱动别混用。5.2 前端 npm install 卡死或报错现象npm install跑一半不动了或者报一堆ERESOLVE依赖冲突。原因网络拉包慢或者依赖树里有版本冲突。解决先换国内镜像源npm config set registry https://registry.npmmirror.com再删掉node_modules和package-lock.json重装。如果还报 ERESOLVE加--legacy-peer-deps参数绕过严格检查。别用--force那个会把依赖装乱。5.3 数据库中文乱码现象页面显示的学生姓名、课程名变成问号或乱码。原因数据库、表、连接串三处的字符集不统一。解决建库时用utf8mb4连接串加characterEncodingutf8MyBatis 的 XML 文件存成 UTF-8 编码。三处都对齐了才不会乱。MySQL 8.0 默认就是 utf8mb45.7 要手动指定。5.4 接口返回 404 或 401现象前端调接口浏览器控制台报 404 或 401。原因404 多半是接口路径写错或后端没启动401 是拦截器把请求拦了没带 token 或 token 过期。解决先在浏览器直接访问接口地址看后端是否响应。如果后端正常检查前端baseURL和接口路径拼接对不对。401 的话看拦截器配置登录接口和静态资源要放行别一股脑全拦。5.5 打包后页面空白现象jar 包启动后访问首页一片空白控制台报资源 404。原因Vue 打包的publicPath配置不对默认是/但放进 SpringBoot 后资源路径变了。解决在vue.config.js里把publicPath改成./重新打包再拷进 static 目录。这个坑很隐蔽本地 dev 模式看不出来一打包就现形。6. 二次开发与功能扩展把这份源码改成你自己的项目拿到一套能跑的源码只是起点答辩时老师最常问的是「你做了什么改进」。所以得会在这套基础上做二次开发。下面说几个投入产出比高的扩展方向。第一个是加「考勤异常预警」。思路是写一个定时任务每天扫一遍考勤记录把连续缺勤超过 N 次的学生筛出来往教师端推消息。用 SpringBoot 的Scheduled注解就能实现Component public class AttendanceWarningTask { Autowired private AttendanceMapper attendanceMapper; // 每天晚 8 点执行 Scheduled(cron 0 0 20 * * ?) public void checkAbsence() { // 查出连续缺勤超过 3 次的学生 ListWarningVO list attendanceMapper.selectContinuousAbsence(3); for (WarningVO vo : list) { // 这里可以接消息推送或写预警表 System.out.println(预警学生 vo.getStudentName()); } } }cron表达式0 0 20 * * ?表示每天 20:00 触发。对应的 SQL 用窗口函数或自连接算连续缺勤MySQL 8.0 支持窗口函数写起来更简洁。这个功能加进去答辩时能讲「从被动记录到主动预警」立意就上去了。第二个是「考勤数据导出 Excel」。教师端经常需要把考勤表导出来存档。用 EasyExcel 或 POI 都行EasyExcel 内存占用低适合大数据量。核心代码就是查数据、写流、设响应头网上模板很多套进去改改字段就行。第三个是「人脸识别签到」这种听起来唬人的功能。实际落地可以用现成的 SDK前端调摄像头拍照后端调接口比对。但这个方向坑很深涉及模型部署和性能毕业设计层面做个 demo 演示即可别真往生产环境想。我一般建议学生把精力放在业务逻辑的完整性上而不是堆花哨功能——老师更看重你对业务流程的理解而不是调了几个 API。验证扩展功能有没有做对我的习惯是先写一条能复现的测试数据手动走一遍流程看数据库里字段变化对不对再看前端展示是否一致。三步都对上了才算真的通了。从那以后我每次改完代码都强制自己走一遍「造数据 → 跑流程 → 查库 → 看页面」这个闭环能挡掉八成低级错误。希望这份拆解能帮你把这套考勤系统真正跑起来、改明白。本文还有配套的精品资源点击获取
📌 标签:
工业官网
设计趋势
AI 建站
SEO
获取完整报告 →
RELATED ARTICLES
推荐阅读
2026/10/7 16:53:30
基于Django的公园定位系统开发实战:从数据模型到地图交互
2026/10/7 16:53:30
DEF CON 33 LiveCTF实战复盘:攻防对抗下的漏洞利用与防御
2026/10/7 16:53:30
Java+Springboot+Vue口腔牙科诊所预约管理系统源码实战:环境搭建、排班冲突校验与二次开发
2026/10/7 18:38:45
用Visual C++与ID3DXSprite实现DSP数据实时可视化指南
2026/10/7 18:38:45
JavaWeb增删改查源码包怎么跑通?从技术栈到部署避坑全解析
2026/10/7 18:38:45
Java在线考试管理系统源码解析:组卷判分与交卷幂等实战
2026/10/7 18:38:45
Cadence AC/STB仿真与PLL死区调试:从仿真到流片的实战方法论
2026/10/7 18:38:45
飞船内景模块化搭建:物理可信的太空场景制作方法论
2026/10/7 18:33:45
传递熵与widelymfx:时间序列因果推断的方向性分析工具
2026/10/7 0:01:56
基于sEMG与IMU的手语手势识别:从数据采集到实时部署避坑指南
2026/10/7 0:01:56
装配车间MES落地指南:SimpleMES工单流转、BOM与齐套检查实战
2026/10/7 0:01:56
AI获客怎样减少重复线索?意客AI的原文复用与版本筛选
2026/10/6 15:41:36
Jev+Agent接管浏览器:browser-use实战与jev-ultrafast性能优化
2026/10/7 9:55:49
多智能体集群实战:DeepAgents编排、MCP与A2A协议及Skills体系
2026/10/7 14:02:03
hindsight:面向LLM应用的事后可观测性工程实践
2026/10/6 21:51:29
我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频
2026/10/6 22:05:33
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证
2026/10/6 22:06:19
2026 大模型集体涨价:用 Python 做企业 Token 成本测算与选型避坑(附配置)