1. 项目概述
这个课堂考勤系统采用SpringBoot+Vue前后端分离架构,主要解决传统纸质点名效率低下、数据难以统计的问题。我在实际开发中发现,一个完善的考勤系统需要同时满足教师便捷操作和学生实时反馈的需求,而市面上很多成品软件要么功能冗余,要么扩展性不足。
系统核心功能包括:教师端的班级管理、考勤记录、数据统计;学生端的签到、请假申请;管理员的权限分配和系统设置。相比同类产品,我们特别优化了移动端适配和离线签到功能,这在网络不稳定的教室环境中尤为重要。
2. 技术架构设计
2.1 后端技术栈
SpringBoot 2.7.3作为核心框架,搭配以下关键组件:
- 持久层:MyBatis-Plus 3.5.1(简化CRUD操作)
- 数据库:MySQL 8.0(主从配置确保高可用)
- 认证授权:Spring Security + JWT
- 实时通信:WebSocket(用于考勤状态推送)
- 缓存:Redis 6.2(存储临时签到令牌)
java复制// 典型Controller示例
@RestController
@RequestMapping("/attendance")
public class AttendanceController {
@Autowired
private AttendanceService attendanceService;
@PostMapping("/record")
public Result recordAttendance(@RequestBody AttendanceDTO dto) {
return attendanceService.handleAttendance(dto);
}
}
2.2 前端技术栈
Vue 3.2 + Element Plus构建的管理后台,主要特点:
- 路由守卫实现权限控制
- Axios封装统一错误处理
- ECharts可视化考勤数据
- 采用Pinia状态管理替代Vuex
javascript复制// 签到组件关键逻辑
const handleSign = async () => {
const { code } = await signApi(studentId.value)
if(code === 200) {
ElMessage.success('签到成功')
attendanceStatus.value = '已签到'
}
}
3. 核心功能实现
3.1 动态考勤码生成
采用Redis实现时效性控制:
- 教师发起考勤时生成6位随机码
- 将
课程ID:随机码作为Key存入Redis(5分钟过期) - 学生签到校验时查询Redis匹配
java复制public String generateCheckCode(Long courseId) {
String code = RandomStringUtils.randomNumeric(6);
String key = "attendance:" + courseId + ":" + code;
redisTemplate.opsForValue().set(key, "1", 5, TimeUnit.MINUTES);
return code;
}
3.2 多维度考勤统计
MySQL聚合查询结合前端可视化:
sql复制SELECT
student_id,
COUNT(CASE WHEN status = 'PRESENT' THEN 1 END) AS present_count,
COUNT(CASE WHEN status = 'LATE' THEN 1 END) AS late_count
FROM attendance_records
WHERE course_id = #{courseId}
GROUP BY student_id
3.3 离线签到机制
通过Service Worker实现:
- 浏览器缓存必要静态资源
- 本地IndexedDB存储签到记录
- 网络恢复后自动同步到服务端
4. 数据库设计
主要表结构说明:
| 表名 | 关键字段 | 索引设计 |
|---|---|---|
| sys_user | id, username, role_type | username唯一索引 |
| course | id, name, teacher_id | teacher_id普通索引 |
| attendance | id, course_id, check_code | (course_id, create_time)联合索引 |
| record | id, student_id, attendance_id, status | (attendance_id, student_id)联合索引 |
特别注意:attendance表需要定期归档,建议按学期分表
5. 部署注意事项
- Nginx配置示例:
nginx复制location /api {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
}
location / {
root /var/www/attendance-system;
try_files $uri $uri/ /index.html;
}
- 常见启动问题排查:
- 端口冲突:检查8080(SpringBoot)和80(Nginx)端口占用
- 数据库连接:确保MySQL max_connections足够
- 跨域问题:开发环境需配置CORS,生产环境通过Nginx解决
6. 性能优化实践
- 考勤记录批量插入:
java复制@Transactional
public void batchInsert(List<AttendanceRecord> records) {
SqlSession session = sqlSessionFactory.openSession(ExecutorType.BATCH);
AttendanceMapper mapper = session.getMapper(AttendanceMapper.class);
records.forEach(mapper::insert);
session.commit();
}
- 前端懒加载优化:
- 路由级组件动态导入
- ECharts按需引入
- 使用v-lazy指令延迟加载图片
7. 扩展功能建议
- 生物识别集成:调用设备摄像头实现人脸识别签到
- 微信小程序端:便于学生快速访问
- 智能预警:自动标记异常考勤模式
- 教室设备对接:与门禁系统联动
我在实际部署中发现,当并发签到超过200人时,需要调整MySQL的innodb_buffer_pool_size(建议设置为物理内存的70%)。另外,使用HikariCP连接池时,maximumPoolSize应根据服务器核心数合理设置,通常推荐CPU核心数*2 + 有效磁盘数。
