毕业设计实战:基于SSM的学生网上请假系统设计与实现全攻略
在开发“学生网上请假系统”这套毕设时,我曾因“请假流程与考勤管理脱节”踩过一个关键坑。初期设计时,我将“学生请假申请”和“考勤记录”视为两个独立的模块,导致学生请假获批后,考勤记录未自动同步更新,教师端看到的考勤状态与请假状态不一致,期末统计时数据混乱,耗费3天重构了请假与考勤的联动机制、引入请假状态机(待审核→班主任审核→系主任审核→通过/拒绝)和考勤自动更新逻辑才解决了问题📝。
基于此次实战经验,本文将精简拆解这套涵盖管理员、系主任、老师、学生四大角色的网上请假系统,分享核心开发流程与实操细节,为同类请假审批类毕设提供一份可落地的参考。
一、需求分析:聚焦“请假审批流程”核心,避免功能冗余
很多同学在做审批类系统时,容易陷入“功能堆砌”的误区。我最初也曾想加入一个复杂的“课程签到地图”模块,结果因偏离“请假申请、多级审批、考勤关联”等核心业务,被导师要求删减。
在做这套系统时,我的核心思路是抓住**“请假”这个事件主体,围绕“审批”这个场景,理清“学生(申请人)”、“老师(班主任审批)”、“系主任(最终审批)”、“管理员(系统管理)”**之间的关系,最终形成 “学生提交请假 → 班主任初审 → 系主任终审 → 通过后自动更新考勤 → 学生查看审批结果” 的业务闭环。
1. 核心角色与功能(精简版)
| 角色 | 核心功能 |
|---|---|
| 管理员 | 系主任管理(增删改查/重置密码)、老师管理、学生管理、班级管理、课程管理、课表管理、公告管理 |
| 系主任 | 请假管理(查看学生请假申请并终审)、学生管理、老师信息查看、考勤统计查看、课程查看、公告管理 |
| 老师(班主任) | 请假管理(初审学生的请假申请)、考勤管理(录入/修改学生考勤)、课程查看、学生信息查看 |
| 学生 | 请假管理(提交请假申请/查看审批进度)、考勤查看、班级查看、课程查看、个人信息管理 |
2. 需求避坑要点
- 拒绝空想,模拟流程:在开发前,我邀请了10名学生、3位班主任和2位系主任模拟了“学生因病请假→提交申请→班主任审批→系主任审批→通过后考勤自动更新→学生查看结果”的完整流程。发现学生最关心“审批进度”,于是增加了“审批状态跟踪(待班主任审核/待系主任审核/已通过/已拒绝)”功能。
- 明确约束条件:提前规定“请假编号自动生成(格式:QJ+年月日+流水号)”“请假天数自动计算(根据开始日期和结束日期)”“请假通过后考勤状态自动更新为请假”“不同请假类型需不同证明材料”,这些明确的约束为后续系统实现提供了清晰的业务边界。
二、技术选型:稳定框架 + 多级审批,新手友好
这套系统涉及多级审批流程,前期我曾尝试使用工作流引擎,结果学习成本高且配置复杂。最终我回归了更简单直接的方案:
| 技术工具 | 选型理由 | 避坑提醒 |
|---|---|---|
| SSM框架(Spring+SpringMVC+MyBatis) | 经典成熟的企业级开发框架,文档丰富,适合审批类系统的稳定开发 | 重点掌握Spring声明式事务管理;请假审批涉及多表操作(请假单状态更新+考勤记录新增)必须加事务 |
| JSP + JSTL + jQuery | 传统的服务端渲染方式,开发简单,适合毕设快速实现 | 使用<c:if>标签根据审批状态显示不同按钮;表单提交用Ajax提升用户体验 |
| MySQL 5.7 | 存储所有业务数据 | 请假表需要请假编号、请假类型、开始/结束日期、请假天数、审批状态等多个字段;考勤表需要关联学生和考勤状态 |
| Bootstrap | 快速搭建响应式前端界面,适配PC端和移动端 | 使用Bootstrap的模态框实现审批弹窗,方便填写审核意见 |
三、数据库设计:业务关联清晰,支撑审批闭环
数据库设计直接影响后续开发效率。前期因未设计“审批状态字段”和“考勤联动机制”,导致请假通过后考勤状态未更新、审批流程不可追溯。
1. 核心表结构(精选核心表)
- 学生表(yonghu):
id、username(学号)、password、clazz_id(班级)、yonghu_uuid_number(学号)、yonghu_name、yonghu_phone、yonghu_id_number、yonghu_photo、sex_types、yonghu_email。 - 老师表(laoshi):
id、username、password、laoshi_uuid_number(工号)、laoshi_name、laoshi_phone、laoshi_id_number、laoshi_photo、sex_types、laoshi_email。 - 系主任表(xizhuren):
id、username、password、xizhuren_uuid_number(工号)、xizhuren_name、xizhuren_phone、xizhuren_id_number、xizhuren_photo、sex_types、xizhuren_email。 - 班级表(clazz):
id、laoshi_id(班主任)、clazz_name、clazz_address。 - 课程表(kecheng):
id、laoshi_id(任课老师)、kecheng_name、kecheng_address、kecheng_types(课程形式)。 - 请假表(qingjia):这是核心业务表。包含
qingjia_uuid_number(请假编号)、yonghu_id(学生)、qingjia_name(请假标题)、qingjia_types(请假类型)、qingjiakaishi_time(开始日期)、qingjia_number(请假天数)、qingjiajieshu_time(结束日期)、qingjia_content(请假内容)、insert_time(申请时间)、qingjia_yesno_types(审批状态:1待班主任审核/2待系主任审核/3已通过/4已拒绝)、qingjia_yesno_text(审核回复)、qingjia_shenhe_time(审核时间)。 - 考勤表(kaoqin):
id、yonghu_id(学生)、kaoqin_types(考勤状态:正常/迟到/早退/旷课/请假)、kaoqin_time(考勤日期)、insert_time(录入时间)。 - 公告表(gonggao):
id、gonggao_name、gonggao_types、insert_time、gonggao_content。
2. 关键业务SQL示例
示例SQL(查询学生的完整请假记录及审批进度):
-- 查询学生“张三”的所有请假记录及审批状态
SELECT
q.qingjia_uuid_number AS leave_no,
q.qingjia_name AS title,
q.qingjia_types AS leave_type,
q.qingjiakaishi_time AS start_date,
q.qingjiajieshu_time AS end_date,
q.qingjia_number AS days,
q.qingjia_content AS reason,
q.insert_time AS apply_time,
q.qingjia_yesno_types AS status, -- 1待班主任/2待系主任/3已通过/4已拒绝
q.qingjia_yesno_text AS reply,
q.qingjia_shenhe_time AS audit_time,
l.laoshi_name AS teacher_name,
x.xizhuren_name AS director_name
FROM qingjia q
LEFT JOIN yonghu y ON q.yonghu_id = y.id
LEFT JOIN clazz c ON y.clazz_id = c.id
LEFT JOIN laoshi l ON c.laoshi_id = l.id
LEFT JOIN xizhuren x ON 1=1 -- 系主任固定,实际可根据业务关联
WHERE y.yonghu_name = '张三'
ORDER BY q.insert_time DESC;
关键避坑:
- 审批状态流转:请假单状态必须按顺序流转:待班主任审核(1)→待系主任审核(2)→已通过/已拒绝(3/4)。班主任审核通过后状态变为2,系主任审核通过后状态变为3。
- 考勤自动更新:请假通过后,需在考勤表中自动插入对应日期的请假记录,标记为请假状态。
- 数据一致性:涉及请假单状态更新和考勤记录插入的多表操作,务必使用事务注解
@Transactional。
四、核心功能实现:6大模块满足答辩需求
这套系统功能点清晰,答辩时只需讲清楚核心业务流程即可。以下6个模块是重中之重,也是答辩评委最可能提问的地方。
1. 请假管理(核心业务流程 - 学生端)
- 核心逻辑:学生提交请假申请→填写请假标题、类型、开始/结束日期、请假内容→系统自动计算请假天数→提交后状态为“待班主任审核”。
- 代码要点:
@Service
@Transactional
public void addQingjia(Qingjia qingjia) {
// 1. 自动生成请假编号 QJ+年月日+流水号
String uuid = "QJ" + LocalDate.now().toString().replace("-", "")
+ String.format("%04d", getTodayCount() + 1);
qingjia.setQingjiaUuidNumber(uuid);
// 2. 自动计算请假天数
long days = ChronoUnit.DAYS.between(
qingjia.getQingjiakaishiTime().toInstant(),
qingjia.getQingjiajieshuTime().toInstant()
);
qingjia.setQingjiaNumber((int) days + 1);
// 3. 设置初始审批状态为“待班主任审核”
qingjia.setQingjiaYesnoTypes(1);
qingjia.setInsertTime(new Date());
qingjia.setCreateTime(new Date());
qingjiaMapper.insert(qingjia);
log.info("学生 {} 提交请假申请,编号:{}", qingjia.getYonghuId(), uuid);
}
2. 请假管理(核心业务流程 - 老师/班主任端)
- 核心逻辑:班主任查看本班学生的请假申请→初审(通过/拒绝)→通过后状态变为“待系主任审核”→填写审核意见。
- 代码要点(班主任初审):
@Service
@Transactional
public void teacherAudit(Integer qingjiaId, Integer status, String reply) {
Qingjia qingjia = qingjiaMapper.selectByPrimaryKey(qingjiaId);
if (qingjia.getQingjiaYesnoTypes() != 1) {
throw new RuntimeException("该请假单状态异常,无法审核");
}
qingjia.setQingjiaYesnoText(reply);
qingjia.setQingjiaShenheTime(new Date());
if (status == 1) { // 通过
qingjia.setQingjiaYesnoTypes(2); // 进入系主任审核
log.info("班主任通过请假申请,进入系主任审核,请假编号:{}", qingjia.getQingjiaUuidNumber());
} else { // 拒绝
qingjia.setQingjiaYesnoTypes(4); // 已拒绝
log.info("班主任拒绝请假申请,请假编号:{}", qingjia.getQingjiaUuidNumber());
}
qingjiaMapper.updateByPrimaryKey(qingjia);
}
3. 请假管理(核心业务流程 - 系主任端)
- 核心逻辑:系主任查看通过班主任初审的请假申请→终审(通过/拒绝)→通过后自动更新考勤记录→填写最终审核意见。
- 代码要点(系主任终审 + 考勤联动):
@Service
@Transactional
public void directorAudit(Integer qingjiaId, Integer status, String reply) {
Qingjia qingjia = qingjiaMapper.selectByPrimaryKey(qingjiaId);
if (qingjia.getQingjiaYesnoTypes() != 2) {
throw new RuntimeException("该请假单状态异常,无法审核");
}
qingjia.setQingjiaYesnoText(reply);
qingjia.setQingjiaShenheTime(new Date());
if (status == 1) { // 通过
qingjia.setQingjiaYesnoTypes(3); // 已通过
// 关键:自动更新考勤记录
updateKaoqinOnLeaveApproved(qingjia);
log.info("系主任通过请假申请,请假编号:{}", qingjia.getQingjiaUuidNumber());
} else { // 拒绝
qingjia.setQingjiaYesnoTypes(4); // 已拒绝
log.info("系主任拒绝请假申请,请假编号:{}", qingjia.getQingjiaUuidNumber());
}
qingjiaMapper.updateByPrimaryKey(qingjia);
}
// 请假通过后更新考勤
private void updateKaoqinOnLeaveApproved(Qingjia qingjia) {
LocalDate start = qingjia.getQingjiakaishiTime().toLocalDate();
LocalDate end = qingjia.getQingjiajieshuTime().toLocalDate();
// 遍历请假日期范围内的每一天,插入考勤记录
for (LocalDate date = start; !date.isAfter(end); date = date.plusDays(1)) {
Kaoqin kaoqin = new Kaoqin();
kaoqin.setYonghuId(qingjia.getYonghuId());
kaoqin.setKaoqinTypes(5); // 5=请假
kaoqin.setKaoqinTime(date);
kaoqin.setInsertTime(new Date());
kaoqin.setCreateTime(new Date());
kaoqinMapper.insert(kaoqin);
}
}
4. 考勤管理(老师端)
- 核心逻辑:老师可以录入/修改学生的日常考勤(正常/迟到/早退/旷课);期末统计学生出勤情况。
- 页面设计:考勤列表按日期倒序排列;支持按班级、学生姓名、日期筛选。
5. 班级与课程管理(管理员端)
- 核心逻辑:管理员管理班级信息(班级名称、位置、班主任);管理课程信息(课程名称、地点、任课老师、课程形式)。
- 代码要点:
public void addClazz(Clazz clazz) {
// 校验班级名称是否重复
ClazzExample example = new ClazzExample();
example.createCriteria().andClazzNameEqualTo(clazz.getClazzName());
List<Clazz> list = clazzMapper.selectByExample(example);
if (!list.isEmpty()) {
throw new RuntimeException("班级名称已存在");
}
clazz.setInsertTime(new Date());
clazz.setCreateTime(new Date());
clazzMapper.insert(clazz);
}
6. 公告管理(系主任/管理员端)
- 核心逻辑:系主任和管理员发布通知公告(放假通知、补课安排等)→学生和老师可查看公告列表和详情。
- 页面设计:公告列表按发布时间倒序排列;支持公告类型分类展示。
五、学生网上请假系统特色功能设计(关键加分项)
这套系统的核心在于“请假审批与考勤管理的完整闭环”,以下几个特色设计能让你的毕设脱颖而出:
1. 多级审批流程可视化
在学生和老师的请假管理界面,用标签清晰展示请假单的审批状态:
- 待班主任审核:显示黄色标签,学生可撤回申请
- 待系主任审核:显示蓝色标签,班主任审核已通过,等待系主任
- 已通过:显示绿色标签,考勤已自动更新
- 已拒绝:显示红色标签,显示拒绝原因
2. 请假与考勤联动统计
-- 统计学生出勤情况(正常/迟到/早退/旷课/请假)
SELECT
y.yonghu_name,
COUNT(CASE WHEN k.kaoqin_types = 1 THEN 1 END) AS normal_days,
COUNT(CASE WHEN k.kaoqin_types = 2 THEN 1 END) AS late_days,
COUNT(CASE WHEN k.kaoqin_types = 3 THEN 1 END) AS early_days,
COUNT(CASE WHEN k.kaoqin_types = 4 THEN 1 END) AS absent_days,
COUNT(CASE WHEN k.kaoqin_types = 5 THEN 1 END) AS leave_days
FROM yonghu y
LEFT JOIN kaoqin k ON y.id = k.yonghu_id
WHERE y.clazz_id = #{clazzId}
GROUP BY y.id;
在系主任和老师后台展示班级出勤统计报表,按月/按学期统计,辅助学生管理决策。
3. 请假审批提醒(可选加分项)
- 学生提交请假后,系统自动通知班主任(站内消息)
- 班主任审批通过后,自动通知系主任
- 最终审批通过/拒绝后,自动通知学生
- 实现方式:数据库消息表 + 前端轮询或WebSocket
4. 请假类型统计分析
-- 统计各类请假类型的占比
SELECT
qingjia_types AS leave_type,
COUNT(*) AS count,
ROUND(COUNT(*) * 100.0 / (SELECT COUNT(*) FROM qingjia), 2) AS percentage
FROM qingjia
WHERE qingjia_yesno_types = 3 -- 已通过的请假
GROUP BY qingjia_types
ORDER BY count DESC;
在管理员后台展示请假类型统计图表,为学校管理提供数据支持(如病假占比高可加强流感预防宣传)。
六、测试与答辩:流程演示为主,突出请假闭环
1. 核心测试用例
| 测试场景 | 操作步骤 | 预期结果 |
|---|---|---|
| 学生提交请假 | 学生登录→新增请假→填写信息→提交 | 请假单生成,状态为“待班主任审核” |
| 班主任初审通过 | 班主任登录→查看请假列表→审核通过 | 请假单状态变为“待系主任审核” |
| 系主任终审通过 | 系主任登录→查看请假列表→审核通过 | 请假单状态变为“已通过”,考勤表自动新增请假记录 |
| 学生查看进度 | 学生登录→查看请假记录 | 审批状态正确显示(待班主任/待系主任/已通过/已拒绝) |
| 考勤统计 | 老师登录→查看考勤统计 | 学生出勤数据准确,包含请假天数 |
2. 答辩准备技巧
- 演示流程:分角色演示,强调闭环。
- 管理员端:展示添加班级、添加学生、添加老师、添加系主任。
- 学生端:展示提交请假申请、查看审批进度。
- 班主任端:展示初审通过、查看班级学生列表。
- 系主任端:展示终审通过。
- 最终展示:在学生端查看请假单状态已变为“已通过”,并在考勤查看中看到对应日期已标记为请假,强调完整的请假-考勤联动闭环。
- 业务讲解:准备一页PPT展示系统业务流程图,从“学生提交请假”到“考勤自动更新”的全过程。
- 技术亮点:
- 多级审批流程设计:如何用状态字段实现待班主任审核→待系主任审核→已通过的流转。
- 事务一致性:系主任终审通过时,同时更新请假单状态和插入考勤记录的事务管理。
- 考勤自动更新算法:如何根据请假开始/结束日期自动生成多天考勤记录。
- 统计报表:出勤统计、请假类型统计的实现。
- 突出问题解决:讲清楚“如何保证请假通过后考勤自动同步”(事务+考勤插入逻辑)、“如何防止重复审批”(状态校验)、“如何实现请假天数自动计算”(日期差计算)。
结语
本文核心是“聚焦网上请假核心业务、实现多级审批与考勤联动、设计一套完整的请假管理系统”。毕设无需追求技术多炫酷,把学生(申请人)、老师(初审人)、系主任(终审人)、**考勤(结果关联)**之间的业务逻辑讲透,实现一个功能完整、流程闭环的系统,就足以成为答辩中的亮点。
若需完整项目源码(带详细注释)、测试数据SQL脚本、以及多级审批和考勤联动的完整代码,可在评论区留言“学生网上请假系统”获取;开发中遇问题(如审批状态流转、考勤自动更新、事务一致性),也可留言咨询~ 祝毕设顺利!🎉