1. 项目概述:基于SpringBoot与Android的学生请销假系统
这个毕业设计项目采用SpringBoot后端+Android客户端的架构,实现了一套完整的校园请销假管理解决方案。作为一名经历过多次校园信息化系统开发的工程师,我认为这类系统在高校管理中具有极高的实用价值——它能将传统纸质请假条电子化,同时解决辅导员、宿管、任课教师多方协同的痛点。
系统核心功能模块包括:学生移动端请假申请、辅导员审批流、销假状态更新、历史记录查询等。技术栈选择上,后端采用SpringBoot 2.7.x + MyBatis Plus + MySQL 8.0,Android端使用Kotlin+Jetpack组件开发,前后端通过RESTful API交互。这种组合既保证了开发效率,又能满足毕业设计对技术深度的要求。
提示:选择SpringBoot而非传统SSM框架,主要考虑其自动配置特性可以大幅减少XML配置工作量,让开发者更专注于业务逻辑实现
2. 系统架构设计解析
2.1 技术选型依据
后端选择SpringBoot框架主要基于三点考量:
- 内嵌Tomcat简化部署,
spring-boot-starter-web依赖一键引入Web MVC组件 - 与MyBatis Plus的完美整合,通过
mybatis-plus-boot-starter实现单表零SQL开发 - Actuator端点提供系统监控能力,方便答辩时展示系统健康状态
Android端采用Kotlin而非Java开发,主要利用其以下优势:
- 空安全特性减少NPE崩溃
- 扩展函数简化View操作代码
- 协程支持使异步代码更易读写
2.2 数据库设计要点
请假系统的核心表结构设计如下(MySQL 8.0):
CREATE TABLE `leave_application` ( `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键', `student_id` varchar(20) NOT NULL COMMENT '学号', `type` tinyint NOT NULL COMMENT '请假类型(1病假/2事假/3公假)', `start_time` datetime NOT NULL COMMENT '开始时间', `end_time` datetime NOT NULL COMMENT '结束时间', `reason` varchar(255) NOT NULL COMMENT '请假事由', `status` tinyint DEFAULT '0' COMMENT '状态(0待审批/1已通过/2已拒绝)', `approver_id` varchar(20) DEFAULT NULL COMMENT '审批人ID', `approve_time` datetime DEFAULT NULL COMMENT '审批时间', `cancel_time` datetime DEFAULT NULL COMMENT '销假时间', PRIMARY KEY (`id`), KEY `idx_student` (`student_id`), KEY `idx_status` (`status`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;注意:datetime类型精确到秒,比timestamp更适请假场景;utf8mb4字符集支持emoji表情输入
3. 核心功能实现细节
3.1 审批状态机设计
请假流程的状态转换采用状态模式实现:
public interface LeaveState { void handle(LeaveApplication context); } @Component @Scope("prototype") public class PendingState implements LeaveState { @Override public void handle(LeaveApplication context) { if (context.getApproverId() != null) { context.setState(SpringContextUtil.getBean(ApprovedState.class)); // 发送站内信通知学生 messageService.send( context.getStudentId(), "您的请假申请已通过审批" ); } } }状态变更时通过Spring事件机制发送通知:
@EventListener public void handleLeaveApprovedEvent(LeaveApprovedEvent event) { PushClient.pushToTeacher( event.getApproverId(), "新请假申请待审批" ); }3.2 Android端关键实现
使用Jetpack组件构建MVVM架构:
- View层:Data Binding + 自定义请假类型选择器
<androidx.cardview.widget.CardView android:layout_width="match_parent" android:layout_height="wrap_content" app:cardCornerRadius="8dp"> <data> <variable name="vm" type="com.example.leave.LeaveViewModel"/> </data> <Spinner android:entries="@array/leave_types" android:selectedItemPosition="@={vm.selectedType}"/> </androidx.cardview.widget.CardView>- 网络层:Retrofit + Kotlin协程
interface LeaveApiService { @POST("/leave/apply") suspend fun applyLeave(@Body request: LeaveRequest): Response<BaseResponse> } class LeaveRepository { private val api = RetrofitClient.create<LeaveApiService>() suspend fun applyLeave(request: LeaveRequest) = withContext(Dispatchers.IO) { api.applyLeave(request) } }4. 开发中的典型问题与解决方案
4.1 时间冲突校验
解决学生重复请假的业务逻辑:
@Transactional public void checkTimeConflict(LeaveApplication application) { LocalDateTime start = application.getStartTime(); LocalDateTime end = application.getEndTime(); Integer count = leaveMapper.selectCount(new QueryWrapper<LeaveApplication>() .eq("student_id", application.getStudentId()) .in("status", 0, 1) // 待审批或已通过 .and(wrapper -> wrapper .between("start_time", start, end) .or() .between("end_time", start, end) ) ); if (count > 0) { throw new BusinessException("该时间段已有生效请假记录"); } }4.2 Android端数据同步
使用WorkManager实现离线申请队列:
class LeaveSyncWorker( context: Context, params: WorkerParameters ) : CoroutineWorker(context, params) { override suspend fun doWork(): Result { val pendingList = database.leaveDao() .getPendingApplications() pendingList.forEach { request -> try { repository.applyLeave(request) database.leaveDao().markAsSynced(request.id) } catch (e: Exception) { return Result.retry() } } return Result.success() } }5. 系统扩展方向建议
- 生物识别集成:在Android端加入人脸识别活体检测,确保请假申请人身份真实
FaceDetectorOptions.Builder() .setPerformanceMode(FaceDetectorOptions.PERFORMANCE_MODE_FAST) .setContourMode(FaceDetectorOptions.CONTOUR_MODE_ALL) .build()- 微信小程序接入:通过SpringBoot同时提供WebAPI给小程序端使用
@RestController @RequestMapping("/mini-program") public class MiniProgramController { @GetMapping("/leave/list") public R<List<LeaveVO>> list(@RequestHeader("X-WX-OPENID") String openId) { // 通过openId关联学生账号 } }- 数据可视化分析:使用ECharts展示各班级请假趋势
// 在管理后台中加入 option = { xAxis: { type: 'category', data: ['周一','周二','周三'] }, yAxis: { type: 'value' }, series: [{ data: [120, 200, 150], type: 'line' }] };在实现这类系统时,我建议特别注意请假流程的幂等性设计——网络抖动可能导致重复提交,可以通过前端防重提交+服务端唯一索引约束共同保障。例如在数据库添加request_id字段并建立唯一索引:
ALTER TABLE `leave_application` ADD COLUMN `request_id` varchar(32) NOT NULL DEFAULT '', ADD UNIQUE INDEX `uk_request` (`request_id`);