
1. 项目背景与核心价值学生请假审批管理系统是高校信息化建设中不可或缺的一环。传统纸质请假流程存在审批效率低、数据统计困难、假条易丢失等问题。我们团队基于SpringBootMySQL技术栈开发的这套系统实现了请假流程的电子化、规范化和可追溯化。这个系统最核心的价值在于将平均审批时间从3天缩短至2小时内实现请假数据的自动化统计与分析建立完整的电子档案留存机制支持多终端访问PC/移动端提示系统已在某高校实际运行一学期处理请假申请超过2000条系统稳定性得到验证。2. 技术架构解析2.1 整体技术选型系统采用经典的三层架构表现层Thymeleaf Bootstrap 业务层SpringBoot 2.7 Spring Security 数据层MySQL 8.0 MyBatis-Plus选择这套技术栈主要基于以下考虑SpringBoot的自动配置特性大幅简化了SSM框架的整合MyBatis-Plus提供的CRUD接口减少30%以上的重复代码MySQL社区版完全满足需求且零成本Bootstrap确保系统在移动端的适配性2.2 核心组件设计系统包含6个核心模块身份认证模块JWT实现请假申请模块审批流程模块数据统计模块系统管理模块消息通知模块每个模块都采用独立package结构通过清晰的接口定义进行交互。例如请假申请模块的类结构- controller - LeaveApplicationController - service - impl - LeaveApplicationServiceImpl - dao - LeaveApplicationMapper - entity - LeaveApplication - dto - LeaveApplicationDTO3. 数据库设计与优化3.1 主要表结构系统共设计12张核心表以下是关键表结构学生表(student)CREATE TABLE student ( id int NOT NULL AUTO_INCREMENT, student_no varchar(20) NOT NULL COMMENT 学号, name varchar(50) NOT NULL, class_id int NOT NULL COMMENT 班级ID, phone varchar(20) DEFAULT NULL, PRIMARY KEY (id), UNIQUE KEY uk_student_no (student_no) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;请假申请表(leave_application)CREATE TABLE leave_application ( id int NOT NULL AUTO_INCREMENT, student_id int NOT NULL, start_time datetime NOT NULL, end_time datetime NOT NULL, leave_type tinyint NOT NULL COMMENT 1-病假 2-事假 3-公假, reason varchar(500) NOT NULL, status tinyint NOT NULL DEFAULT 0 COMMENT 0-待审批 1-已通过 2-已拒绝, approver_id int DEFAULT NULL COMMENT 审批人ID, approve_time datetime DEFAULT NULL, create_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id), KEY idx_student_id (student_id), KEY idx_status (status) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;3.2 性能优化措施针对高频查询场景做了以下优化为status字段添加索引加速审批列表查询使用MyBatis-Plus的分页插件实现物理分页对历史请假数据按月分表存储使用Redis缓存常用字典数据4. 核心功能实现细节4.1 审批流程设计系统采用状态机模式管理审批流程public enum LeaveStatus { PENDING(0, 待审批), APPROVED(1, 已通过), REJECTED(2, 已拒绝); // 省略getter/setter } public void approveApplication(int applicationId, int approverId, boolean isApproved) { LeaveApplication application mapper.selectById(applicationId); if (application.getStatus() ! LeaveStatus.PENDING.getCode()) { throw new BusinessException(当前状态不可审批); } application.setStatus(isApproved ? LeaveStatus.APPROVED.getCode() : LeaveStatus.REJECTED.getCode()); application.setApproverId(approverId); application.setApproveTime(new Date()); mapper.updateById(application); // 发送通知 notifyService.sendApproveResult(application); }4.2 数据统计功能使用MyBatis的注解方式实现复杂统计查询Select(SELECT leave_type, COUNT(*) as count FROM leave_application WHERE create_time BETWEEN #{start} AND #{end} GROUP BY leave_type) Results({ Result(property type, column leave_type), Result(property count, column count) }) ListLeaveStatistic getLeaveStatistics(Param(start) Date start, Param(end) Date end);前端使用ECharts展示统计结果function renderStatChart(data) { const chart echarts.init(document.getElementById(chart)); const option { tooltip: {}, xAxis: { data: data.map(item LEAVE_TYPES[item.type]) }, yAxis: {}, series: [{ type: bar, data: data.map(item item.count) }] }; chart.setOption(option); }5. 系统安全设计5.1 认证与授权采用JWT Spring Security实现安全控制Configuration EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { Override protected void configure(HttpSecurity http) throws Exception { http.csrf().disable() .authorizeRequests() .antMatchers(/api/auth/**).permitAll() .antMatchers(/student/**).hasRole(STUDENT) .antMatchers(/teacher/**).hasRole(TEACHER) .anyRequest().authenticated() .and() .addFilter(new JwtAuthenticationFilter(authenticationManager())) .addFilter(new JwtAuthorizationFilter(authenticationManager())); } }5.2 敏感数据保护密码使用BCrypt加密存储日志系统自动脱敏手机号等敏感信息接口参数使用XSS过滤器处理6. 部署与运维方案6.1 生产环境部署推荐部署方案服务器2核4G云服务器JDKAmazon Corretto 11数据库MySQL 8.0主从架构缓存Redis 6.x部署方式Docker容器化启动命令示例java -jar -Dspring.profiles.activeprod \ -Xms512m -Xmx1024m \ student-leave-system.jar6.2 监控与维护使用Spring Boot Actuator暴露健康检查端点配置Logback日志按天归档使用Prometheus Grafana监控系统指标7. 常见问题排查7.1 性能问题问题现象审批列表加载缓慢解决方案检查是否缺少status字段索引确认MyBatis是否启用二级缓存分析慢查询日志EXPLAIN SELECT * FROM leave_application WHERE status 0 ORDER BY create_time DESC;7.2 并发问题问题现象多人同时审批时状态异常解决方案Transactional public void approveApplication(int applicationId, int approverId) { // 使用select...for update加锁 LeaveApplication application mapper.selectByIdForUpdate(applicationId); if (application.getStatus() ! 0) { throw new BusinessException(申请已被处理); } // 更新逻辑... }8. 扩展与优化方向流程引擎集成考虑接入Activiti实现更复杂的审批流程移动端适配开发微信小程序版本智能审批引入规则引擎实现自动审批数据可视化增强统计分析功能经验分享在实际开发中我们发现使用MyBatis-Plus的Lambda查询可以大幅提升代码可读性。例如ListLeaveApplication list lambdaQuery() .eq(LeaveApplication::getStatus, 0) .between(LeaveApplication::getCreateTime, start, end) .list();