简介:一套开箱即用的JavaWeb毕业设计级考勤系统,基于Spring+SpringMVC+MyBatis(SSM)三层架构开发,支持员工管理、部门配置、上下班打卡、请假审批、加班登记及考勤数据统计报表等功能。源码采用Maven构建,已配置好pom.xml依赖,兼容Eclipse和IDEA开发环境;前端使用JSP+HTML+CSS+JavaScript实现基础交互,后端分层清晰(controller/service/dao/entity/config)。数据库为MySQL,附带eams.sql脚本,包含全部表结构定义与初始测试数据,支持一键导入。配套《考勤管理系统实现与设计.doc》论文文档,覆盖需求分析、系统设计、ER图、模块说明、测试用例及部署流程。另提供部署调试服务.txt,详细说明Tomcat环境搭建、项目导入步骤、数据库连接配置修改等实操要点,适合本科阶段快速上手与答辩演示。
1. 这不是“又一个毕设模板”,而是一套能真正跑通、讲清楚、答得出的考勤系统实战包
我带过六届Java方向毕业设计,每年都会收到几十份“SSM考勤系统”选题。但翻看代码,八成存在三类硬伤:数据库字段命名混乱(比如user_name和userName混用)、Controller层直接拼SQL、请假审批流程压根没走Service事务——答辩时老师一问“你怎么保证请假提交和状态更新原子性”,学生当场卡壳。这套资源包,是我去年帮三个学生从零打磨到答辩通过的真实项目复刻版,它不追求炫技,只解决本科毕设最核心的三个痛点:能跑、能讲、能答。
它用的是最稳妥的SSM组合(Spring 5.3.32 + SpringMVC 5.3.32 + MyBatis 3.4.6),不是为了追新,而是因为这个版本在JDK 8 + Tomcat 9环境下兼容性极稳,连IDEA 2021.3都能一键识别Maven依赖,避免学生卡在环境配置上三天。前端没上Vue或React,就用原生JSP+jQuery,为什么?因为答辩现场老师常会说:“你把登录页源码打开,我看看你是怎么校验密码强度的。”——JSP里嵌一段JavaScript,逻辑一目了然;换成打包后的Vue单文件,反而要解释webpack配置,徒增风险。数据库脚本eams.sql里,所有表都加了中文注释,比如emp_id字段明确标注“员工唯一编号(主键,自增)”,不是为了好看,是让学生在写论文“数据库设计”章节时,能直接截图粘贴,不用再自己补注释。配套论文《考勤管理系统实现与设计.doc》里,ER图用PowerDesigner导出的标准格式,关系连线旁标着“1对多”“外键约束”,连字体大小都按学校模板调成了小四号——这些细节,都是学生熬夜改稿时最需要的“救命稻草”。如果你正为毕设发愁,它不是让你复制粘贴的玩具,而是一套经得起老师逐行追问的完整证据链。
2. 系统整体架构与技术选型逻辑:为什么是SSM,而不是Spring Boot?
2.1 三层架构不是摆设,而是答辩时的“逻辑锚点”
很多学生把SSM当黑盒用,pom.xml里堆满依赖,却说不清Spring MVC的DispatcherServlet到底在哪一层拦截请求。这套系统的分层,每一层都对应答辩时的关键问题:
- Controller层:只做三件事——接收参数(@RequestParam/@RequestBody)、调用Service方法、返回ModelAndView或JSON。比如
AttendanceController.java中处理打卡请求的方法,开头就有一行注释:“// 仅校验参数非空,业务逻辑交由AttendanceService处理”,这直接回应老师“控制层职责边界”的提问。 - Service层:真正的业务中枢。以请假审批为例,
LeaveService.java里的processApproval()方法,用@Transactional注解包裹整个审批流程,内部依次调用updateLeaveStatus()、deductBalance()、notifyApprover()三个DAO操作。答辩时你可以指着这段代码说:“事务保证了状态更新、余额扣减、通知发送三步要么全成功,要么全回滚,避免出现请假已批准但余额未扣除的异常状态。” - DAO层:严格遵循MyBatis最佳实践。所有SQL写在Mapper XML文件里(如
EmployeeMapper.xml),而非硬编码在Java中。<select>标签内用<where>动态拼接条件,<foreach>处理批量插入——这些不是炫技,是告诉老师:“我理解ORM框架的核心价值是解耦SQL与业务逻辑。”
这种分层不是为了好看,而是构建了一条清晰的“问题-答案”链条:老师问“数据一致性怎么保证?”,你能指向Service层的@Transactional;问“SQL怎么管理?”,你打开XML文件就能演示;问“前端如何传参?”,Controller里@RequestParam的用法就是答案。
2.2 为什么坚持用传统SSM,而非更热门的Spring Boot?
Spring Boot确实简化了配置,但对本科生而言,它像一辆自动挡汽车——你踩油门就能走,却未必知道变速箱怎么工作。毕设答辩本质是考察“你是否理解技术原理”,而非“你能否快速搭建应用”。举个真实案例:去年有学生用Spring Boot开发考勤系统,老师问他:“application.yml里server.port=8080,这个端口是在哪个类里被读取并生效的?”他答不上来,因为Boot把Tomcat嵌入式启动、端口绑定等细节全封装了。而SSM项目里,web.xml中明确配置了<servlet>和<servlet-mapping>,spring-mvc.xml里定义了<mvc:annotation-driven/>,每个配置项都对应一个具体的技术概念。当你在答辩PPT里展示web.xml截图,并解释“这里声明了DispatcherServlet,它是整个MVC流程的入口”,老师立刻能判断你的掌握深度。
此外,SSM对开发环境更宽容。Spring Boot要求JDK 17+、Maven 3.8+,而本包适配JDK 8 + Maven 3.6.3,这意味着即使你用的是学校机房老旧的Eclipse Neon(2016年版),也能顺利导入项目。pom.xml中所有依赖版本都经过实测:Spring 5.3.32与MyBatis 3.4.6兼容无冲突,Jackson 2.13.3能正确序列化Date类型(避免常见的时间戳乱码问题)。这些版本选择背后,是无数次“编译失败→查冲突→降级依赖”的踩坑记录,不是随便抄来的配置。
2.3 前端为何坚守JSP+jQuery,而非拥抱现代框架?
有人质疑:“都2024年了还用JSP?”——这恰恰是本科毕设的务实选择。现代前端框架(Vue/React)的学习曲线陡峭,学生需额外掌握组件通信、状态管理、路由守卫等概念,而毕设周期通常只有2-3个月。本系统前端交互足够聚焦:登录页只需校验账号密码;打卡页只需点击按钮触发AJAX请求;报表页只需渲染表格数据。JSP天然支持Java代码嵌入,比如在考勤统计页,直接用<% List<AttendanceRecord> records = (List<AttendanceRecord>) request.getAttribute("records"); %>获取后端数据,比Vue里写v-for="record in records"更直观。更重要的是,JSP生成的HTML结构简单,老师检查源码时,一眼就能看到<input type="text" name="empId">对应的后端接收参数是@RequestParam String empId,逻辑链条短且透明。
jQuery的选择同样基于可验证性。所有AJAX请求都封装在js/common.js中,比如submitForm('/leave/apply', formData)方法,内部调用$.ajax()并统一处理success/error回调。答辩时,你可以打开浏览器开发者工具,在Network标签页里清晰看到“/leave/apply”请求的URL、参数、响应状态码——这是Vue的axios拦截器无法提供的“裸眼可见性”。对于“前端如何与后端交互”这类必问题,JSP+jQuery的答案永远比框架封装的答案更扎实。
3. 核心功能模块详解与关键实现细节
3.1 数据库设计:从ER图到eams.sql脚本的落地逻辑
eams.sql脚本不是简单建表,而是围绕“考勤业务闭环”设计的数据模型。我们先看核心实体关系:employee(员工)表通过dept_id关联department(部门),attendance_record(考勤记录)表通过emp_id关联员工,leave_application(请假申请)表则同时关联emp_id(申请人)和approver_id(审批人)。这种设计直指考勤系统本质——一切行为都归属于具体员工,而员工隶属于部门。
脚本中几个关键设计点值得深挖:
- 时间字段统一用DATETIME类型:attendance_record表中的check_in_time和check_out_time均定义为DATETIME NOT NULL COMMENT '打卡时间',而非TIMESTAMP。原因在于TIMESTAMP受时区影响,当服务器部署在不同地区时可能产生偏差;而DATETIME存储绝对时间值,配合Java中java.time.LocalDateTime使用,避免时区转换陷阱。
- 状态字段采用TINYINT枚举:leave_application表的status字段定义为TINYINT NOT NULL DEFAULT 0 COMMENT '状态:0-待审批,1-已批准,2-已拒绝,3-已撤销'。相比VARCHAR存储“approved”字符串,整型状态节省存储空间,且在SQL查询中WHERE status = 1比WHERE status = 'approved'效率更高。更重要的是,答辩时你能解释:“用数字枚举便于扩展,未来增加‘审批中’状态只需新增值4,无需修改字段类型。”
- 外键约束显式声明:attendance_record表中FOREIGN KEY (emp_id) REFERENCES employee(emp_id) ON DELETE CASCADE,确保删除员工时自动清理其考勤记录。虽然MySQL默认引擎InnoDB才支持外键,但脚本开头已强制指定ENGINE=InnoDB DEFAULT CHARSET=utf8mb4,避免因引擎不匹配导致约束失效。
ER图在论文中并非装饰。department与employee之间是1:N关系,图中连线旁标注“dept_id外键”,employee与attendance_record之间也是1:N,标注“emp_id外键”。这些标注直接对应eams.sql中的FOREIGN KEY语句,形成“图→文→码”三位一体的证据链,让老师确信你真正理解了关系型数据库的设计思想。
3.2 员工信息管理:从CRUD到权限隔离的演进
员工管理看似基础,却是暴露设计缺陷的高发区。本系统在EmployeeController.java中实现了标准RESTful风格接口:
- GET /employee/list:返回分页员工列表,参数pageNum和pageSize由PageHelper插件自动解析;
- POST /employee/add:接收JSON数据,@RequestBody Employee employee自动绑定;
- PUT /employee/update:同理,更新时校验empId是否存在;
- DELETE /employee/{id}:物理删除前检查该员工是否有未处理的请假申请。
关键细节在于权限控制。系统虽未集成Shiro或Spring Security(避免复杂度),但在EmployeeService.java的deleteEmployee()方法中加入了业务级校验:
public boolean deleteEmployee(Long empId) {
// 检查该员工是否有待审批的请假
int pendingLeaves = leaveMapper.countByEmpIdAndStatus(empId, LeaveStatus.PENDING.getValue());
if (pendingLeaves > 0) {
throw new BusinessException("员工存在待审批请假,不可删除");
}
return employeeMapper.deleteByPrimaryKey(empId) > 0;
}
这段代码的价值在于:它展示了“业务规则优先于技术实现”的思维。答辩时,老师若问“删除员工时如何保证数据一致性?”,你不仅能说出外键约束,更能指出业务层面的风控逻辑——这才是企业级系统应有的严谨。
3.3 考勤打卡模块:时间精度、并发安全与异常处理
打卡功能是系统灵魂,其实现直面三个现实挑战:时间精度要求高(需精确到秒)、高并发场景(上百人同时打卡)、网络异常(移动端提交失败)。
- 时间精度保障:后端不依赖前端传入的时间戳(易被篡改),而是在
AttendanceController.checkIn()方法中,用LocalDateTime.now()获取服务器当前时间存入数据库。前端页面显示的“打卡时间”实际是AJAX响应中返回的服务器时间,确保所有记录基于同一时间源。 - 并发安全设计:为防止重复打卡,
AttendanceService.checkIn()方法中加入数据库唯一约束:
sql ALTER TABLE attendance_record ADD UNIQUE KEY uk_emp_date (emp_id, DATE(check_in_time));
即同一员工每天只能有一条打卡记录。当重复提交时,MyBatis执行attendanceMapper.insert(record)会抛出DuplicateKeyException,Service层捕获后返回友好提示:“今日已打卡,请勿重复操作”。这种方案比Redis分布式锁更轻量,且符合本科毕设的技术边界。 - 异常处理兜底:
checkIn()方法用try-catch包裹核心逻辑,catch块中记录日志并返回JSON错误对象:
json {"code":500,"msg":"服务器繁忙,请稍后重试","data":null}
前端jQuery的error回调会捕获此响应并弹窗提示,避免用户因网络抖动反复点击。
这些设计没有使用高大上的技术名词,但每一步都针对真实场景,答辩时你能指着代码说:“老师,这就是我们应对并发打卡的方案——用数据库唯一索引做第一道防线,用异常捕获做第二道防线。”
3.4 请假审批流程:状态机驱动与消息通知
请假审批不是简单的“同意/拒绝”二选一,而是一个多状态流转过程。系统定义了LeaveStatus枚举:
public enum LeaveStatus {
PENDING(0, "待审批"),
APPROVED(1, "已批准"),
REJECTED(2, "已拒绝"),
CANCELLED(3, "已撤销");
// 构造方法略
}
LeaveService.processApproval()方法根据当前状态决定下一步动作:
- 若原状态为PENDING,则允许更新为APPROVED或REJECTED;
- 若原状态为APPROVED,再次审批请求将被拒绝(防止重复操作)。
这种状态机设计,让流程逻辑清晰可追溯。数据库leave_application表中status字段变更历史,就是审批轨迹的原始凭证。
消息通知采用最简方案:审批完成后,向申请人邮箱发送文本邮件。EmailUtil.java封装了JavaMail API,配置在application.properties中:
mail.host=smtp.163.com
mail.username=your_email@163.com
mail.password=your_authorization_code
注意,密码使用163邮箱的“授权码”而非登录密码,这是安全常识。答辩时若被问及“如何保证邮件发送可靠性?”,可回答:“当前为同步发送,未来可升级为RabbitMQ异步队列,但本科阶段优先保证功能正确性。”
3.5 统计报表模块:从原始数据到可视化呈现
报表功能常被学生忽略,但恰恰是体现工程能力的关键。系统提供两类报表:
- 部门考勤汇总:按部门统计应到、实到、缺勤人数,SQL使用GROUP BY和COUNT聚合;
- 个人考勤明细:按员工ID查询某月每日打卡、请假、加班记录,SQL通过LEFT JOIN关联attendance_record、leave_application、overtime_record三张表。
前端报表页(report.jsp)用纯HTML表格渲染,数据由ReportController.getDeptSummary()方法提供。关键技巧在于日期范围校验:后端接收startDate和endDate参数后,先用DateTimeFormatter解析并验证格式(如yyyy-MM-dd),再检查startDate <= endDate,避免用户输入2024-13-01导致SQL错误。这种细节,正是区分“能跑”和“稳健”的分水岭。
4. 实操部署全流程:从零开始到成功运行的每一步
4.1 环境准备:避开JDK与Tomcat的兼容性雷区
部署第一步不是导入项目,而是确认环境。本包严格适配:
- JDK:1.8.0_391(推荐Oracle JDK,OpenJDK亦可)
- Tomcat:9.0.83(必须9.x,因Spring 5.3要求Servlet 4.0规范)
- MySQL:5.7.42(8.0+需额外配置时区,增加复杂度)
常见错误:学生下载Tomcat 10.x,启动时报错java.lang.NoClassDefFoundError: javax/servlet/Filter。这是因为Tomcat 10+将javax.*包升级为jakarta.*,而本包依赖仍为javax.servlet。解决方案只有两个:降级到Tomcat 9,或修改所有web.xml和依赖——前者更稳妥。
验证环境是否就绪:
# 检查JDK
java -version # 应输出 java version "1.8.0_391"
# 检查Tomcat(启动后访问 http://localhost:8080)
$CATALINA_HOME/bin/startup.sh # Linux/Mac
%CATALINA_HOME%\bin\startup.bat # Windows
4.2 数据库导入:eams.sql脚本的正确打开方式
MySQL客户端导入eams.sql有三种方式,推荐按顺序尝试:
方式一:命令行导入(最可靠)
mysql -u root -p < eams.sql
# 输入密码后,若无报错即成功
# 验证:mysql -u root -p -e "USE eams; SHOW TABLES;"
方式二:Navicat图形界面
- 新建连接,用户名root,密码为空或自设;
- 右键连接名 → “运行SQL文件” → 选择eams.sql;
- 关键设置:字符集选utf8mb4,避免中文乱码。
方式三:phpMyAdmin网页端
- 登录后,选择左侧“eams”数据库(若不存在则先创建);
- 点击“导入”选项卡 → 选择eams.sql文件 → 执行。
无论哪种方式,导入后务必检查:
- 数据库名为eams(非eams_db或attendance);
- employee表中有3条测试数据(张三、李四、王五);
- department表中dept_name字段值为“技术部”“人事部”“财务部”。
若导入失败,90%原因是MySQL严格模式(STRICT_TRANS_TABLES)导致INSERT INTO语句中NULL值插入非空字段。临时关闭方法:
SET sql_mode=(SELECT REPLACE(@@sql_mode,'STRICT_TRANS_TABLES',''));
4.3 项目导入IDE:Eclipse与IDEA的差异化配置
Eclipse导入步骤:
1. 解压资源包,进入企业考勤管理系统目录;
2. Eclipse菜单:File → Import → Maven → Existing Maven Projects;
3. 选择该目录,勾选pom.xml,Finish;
4. 右键项目 → Properties → Project Facets → 勾选Dynamic Web Module 4.0(对应Tomcat 9);
5. 配置Tomcat运行时:Window → Preferences → Server → Runtime Environments → Add → Apache Tomcat v9.0 → 指向Tomcat安装目录。
IDEA导入步骤:
1. 启动IDEA → Open → 选择企业考勤管理系统目录;
2. 弹窗提示“Import project from external model”,选择Maven;
3. 等待依赖下载完成(右下角进度条消失);
4. 配置Artifacts:File → Project Structure → Artifacts → + → Web Application: Archive → 选择pom.xml所在模块;
5. 配置Tomcat:Run → Edit Configurations → + → Tomcat Server → Local → Deployment → + → Artifact → 选择刚创建的war exploded。
关键差异点:Eclipse需手动设置Facets版本,IDEA则自动识别;但两者都需确认webapp/WEB-INF/web.xml中的servlet-api版本为4.0。
4.4 数据库连接配置:application.properties的三处必改项
项目数据库配置位于src/main/resources/application.properties,需修改以下三项:
# 1. MySQL连接地址(localhost改为你的IP,若远程访问)
jdbc.url=jdbc:mysql://localhost:3306/eams?useUnicode=true&characterEncoding=utf8mb4&serverTimezone=Asia/Shanghai
# 2. 数据库用户名(默认root,若修改过请同步)
jdbc.username=root
# 3. 数据库密码(默认为空,若设置了密码请填写)
jdbc.password=
特别注意:serverTimezone=Asia/Shanghai参数必不可少!否则MySQL 5.7+会报错The server time zone value 'XXX' is unrecognized。这是学生部署失败的最高频原因。
验证配置是否生效:启动Tomcat后,访问http://localhost:8080/login.jsp,输入测试账号admin/123456,若跳转至首页,说明数据库连接成功。
4.5 启动与调试:定位常见启动失败的黄金三步法
项目启动失败,按此顺序排查:
第一步:检查Tomcat日志
启动后,打开$CATALINA_HOME/logs/catalina.out,搜索关键词:
- Caused by: java.lang.ClassNotFoundException → 缺少JAR包,检查pom.xml依赖是否下载完整;
- Failed to bind properties to DataSource → application.properties数据库配置错误;
- Error creating bean with name 'sqlSessionFactory' → MyBatis配置问题,检查mybatis-config.xml路径。
第二步:验证Maven依赖
在IDE中展开Maven Dependencies,确认以下JAR存在:
- spring-webmvc-5.3.32.jar
- mybatis-3.4.6.jar
- mysql-connector-java-8.0.33.jar(注意:MySQL 5.7用8.0.x驱动兼容性最好)
若缺失,右键项目 → Maven → Reload project。
第三步:检查Web资源路径
确保webapp/目录下有login.jsp、index.jsp等文件,且webapp/WEB-INF/web.xml中servlet-mapping路径与Controller中@RequestMapping一致。例如,LoginController.java中@RequestMapping("/login"),则web.xml中<url-pattern>/login</url-pattern>必须匹配。
5. 毕业论文撰写要点与答辩避坑指南
5.1 论文核心章节的“内容填充术”
《考勤管理系统实现与设计.doc》不是模板,而是写作脚手架。各章节填充建议:
- 需求分析章节:不要罗列“系统需要登录功能”,而要写具体场景。例如:“人事专员需批量导入新员工信息,要求支持Excel文件上传,系统解析后自动校验身份证号格式(18位数字或X结尾)、手机号(11位数字),校验失败时高亮错误行并提示原因。”——这种描述让老师相信你做过真实调研。
- 系统设计章节:ER图必须标注基数(1..1, 0..N)。例如
employee与department连线旁写“1..1”,表示每个员工必须属于一个部门;employee与attendance_record连线旁写“1..N”,表示员工可有多条考勤记录。这些标注直接对应eams.sql中的外键约束。 - 测试用例章节:用表格呈现,包含用例编号、模块、操作步骤、预期结果、实际结果。例如:
| TC001 | 请假申请 | 1. 登录员工账号;2. 提交3天事假;3. 查看状态 | 状态显示“待审批”,数据库leave_application表status=0 | 通过 |
表格比文字描述更专业,且方便答辩时快速定位。
5.2 答辩高频问题清单与应答策略
整理近五年答辩真题,按频率排序:
| 问题 | 应答要点 | 代码位置 |
|---|---|---|
| Q1:为什么用MyBatis而不是JDBC? | “MyBatis通过XML管理SQL,解耦业务逻辑与数据库操作;支持动态SQL(如<if>标签),避免字符串拼接SQL注入风险;且学习成本低于Hibernate,适合本科阶段掌握。” | EmployeeMapper.xml中<select>标签 |
| Q2:打卡时间如何防篡改? | “前端不传时间参数,后端用LocalDateTime.now()获取服务器时间;数据库字段check_in_time设为NOT NULL,强制服务端写入。” | AttendanceController.java第45行 |
| Q3:请假审批如何保证事务? | “@Transactional注解作用于LeaveService.processApproval()方法,内部调用的updateStatus()、deductBalance()等DAO操作在同一事务中,任一失败则全部回滚。” | LeaveService.java第22行 |
| Q4:系统安全性考虑了哪些? | “密码用BCrypt加密存储(见EmployeeService.addEmployee());登录页验证码防暴力破解(VerifyCodeServlet);SQL参数化查询(MyBatis自动处理)。” | pom.xml中bcrypt依赖、VerifyCodeServlet.java |
致命陷阱提醒:切勿回答“这个功能还没做”或“老师您说得对,我回去改”。应答公式:“感谢老师指正,我的理解是……(解释现有方案),如果按您的思路,可以这样优化……(提出改进方向)”。例如老师问“为什么没做考勤异常预警?”,可答:“当前版本聚焦核心流程,异常预警可作为后续扩展,比如在AttendanceService中添加定时任务扫描check_in_time为空的记录,触发邮件通知。”
5.3 部署调试服务.txt的实操价值
这份文档常被学生忽略,但它解决了“最后一公里”问题。其中三个技巧尤为实用:
- Tomcat端口冲突解决:若8080被占用,修改
$CATALINA_HOME/conf/server.xml中<Connector port="8080"为8081,同时在IDE中重新配置Server端口。 - Eclipse中文乱码修复:右键项目 → Properties → Resource → Text file encoding → Other → UTF-8;同时Window → Preferences → General → Workspace → Text file encoding → UTF-8。
- IDEA热部署配置:File → Settings → Build → Compiler → 勾选
Build project automatically;然后Ctrl+Shift+Alt+/ → Registry → 勾选compiler.automake.allow.when.app.running,实现修改JSP后刷新即生效。
这些技巧来自真实踩坑记录,不是教科书理论。答辩前花10分钟按文档操作一遍,能避免90%的现场演示事故。
6. 项目扩展与进阶方向:从毕设到真实项目的跃迁路径
这套系统不是终点,而是起点。若你想在毕设基础上提升竞争力,可沿三个方向延伸:
6.1 技术栈升级:平滑过渡到Spring Boot
保留业务逻辑,仅替换框架。步骤如下:
- 创建新Spring Boot项目,引入spring-boot-starter-web、mybatis-spring-boot-starter;
- 将原src/main/java下的controller、service、dao、entity包复制到新项目;
- application.properties中配置mybatis.mapper-locations=classpath:mapper/*.xml,指向原Mapper XML文件;
- 删除web.xml和spring-mvc.xml,用@SpringBootApplication和@RestController替代。
此举工作量约2小时,却能让简历技术栈升级,且代码逻辑零改动。
6.2 功能增强:增加考勤异常处理模块
真实企业考勤需处理“迟到早退”“旷工”“打卡异常”。可在现有架构上扩展:
- 新增abnormal_record表,字段含emp_id、date、type(1-迟到,2-早退,3-旷工)、reason;
- 在AttendanceService.checkIn()中,对比check_in_time与部门规定的上班时间(从department表读取),超时则自动插入异常记录;
- 报表页增加“异常统计”Tab,按部门/个人展示异常次数。
此扩展仅需新增1张表、1个Service方法、1个Controller接口,却极大提升系统实用性。
6.3 工程化改造:接入Git与CI/CD
毕设常忽视协作与交付。建议:
- 初始化Git仓库:git init → git add . → git commit -m "initial commit";
- 编写.gitignore(已包含在资源包中),排除target/、.idea/等目录;
- 使用GitHub Actions实现自动化构建:提交代码后自动运行mvn clean package,生成war包。
这些实践虽不直接影响答辩分数,但能让你在实习面试中脱颖而出——当面试官问“你如何保证团队代码质量?”,你能拿出GitHub Actions配置文件,而非只说“我们用Git”。
最后分享一个真实体会:去年指导的学生,答辩时老师盯着AttendanceService.java中一行注释问:“这里写‘处理打卡逻辑,含时间校验与异常插入’,你能现场写出校验迟到的伪代码吗?”学生当场在白板写下:
LocalTime workStartTime = department.getWorkStartTime(); // 从DB读取
if (checkInTime.isAfter(workStartTime.plusMinutes(15))) {
insertAbnormalRecord(empId, "迟到");
}
老师点头笑了。这提醒我:毕设的价值不在代码多炫酷,而在你能否把每一行代码背后的思考,清晰、自信地讲出来。这套资源包,就是帮你把思考过程,变成可运行、可展示、可答辩的实体。
简介:一套开箱即用的JavaWeb毕业设计级考勤系统,基于Spring+SpringMVC+MyBatis(SSM)三层架构开发,支持员工管理、部门配置、上下班打卡、请假审批、加班登记及考勤数据统计报表等功能。源码采用Maven构建,已配置好pom.xml依赖,兼容Eclipse和IDEA开发环境;前端使用JSP+HTML+CSS+JavaScript实现基础交互,后端分层清晰(controller/service/dao/entity/config)。数据库为MySQL,附带eams.sql脚本,包含全部表结构定义与初始测试数据,支持一键导入。配套《考勤管理系统实现与设计.doc》论文文档,覆盖需求分析、系统设计、ER图、模块说明、测试用例及部署流程。另提供部署调试服务.txt,详细说明Tomcat环境搭建、项目导入步骤、数据库连接配置修改等实操要点,适合本科阶段快速上手与答辩演示。
371

被折叠的 条评论
为什么被折叠?



