1. 项目背景与核心功能解析
这个基于微信小程序的课堂点名系统,是我在疫情期间为高校教师开发的一款轻量级教学工具。当时观察到很多老师还在使用纸质点名册或Excel表格进行考勤,既低效又容易出错。特别是在大教室上课时,传统点名方式会浪费大量宝贵的课堂时间。
系统采用SpringBoot+微信小程序的架构组合,主要实现了以下核心功能:
- 教师端微信小程序:创建课程、管理班级、发起点名、查看考勤统计
- 学生端微信小程序:扫码签到、补签申请、考勤记录查询
- 后台管理系统:数据可视化报表导出、学期考勤汇总
技术选型思考:微信小程序相比原生App更适合教育场景,无需安装且打开即用;SpringBoot后端则提供了快速开发RESTful API的能力,与小程序前端天然契合。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 系统架构设计与技术栈详解
2.1 整体架构分层
系统采用典型的三层架构:
code复制客户端层(微信小程序)
↑↓ HTTP/HTTPS
业务逻辑层(SpringBoot)
↑↓ JDBC
数据持久层(MySQL + Redis)
2.2 关键技术组件
微信小程序端关键实现:
- 使用
wx.login获取用户唯一标识 wx.scanCode实现扫码签到功能- 自定义组件实现日历式考勤展示
- 订阅消息模板推送考勤结果
SpringBoot后端核心配置:
yaml复制# application.yml关键配置
weixin:
appid: wx258xxxx
secret: xxxxx
token-expire: 7200
spring:
datasource:
url: jdbc:mysql://localhost:3306/rollcall?useSSL=false
username: root
password: 123456
redis:
host: 127.0.0.1
port: 6379
2.3 数据库设计要点
主要表结构设计原则:
- 学生表(student)与课程表(course)多对多关系
- 考勤记录表(attendance)包含经纬度字段防作弊
- 使用Redis缓存高频访问的课程信息
sql复制CREATE TABLE `attendance` (
`id` bigint NOT NULL AUTO_INCREMENT,
`student_id` varchar(32) NOT NULL,
`course_id` bigint NOT NULL,
`status` tinyint DEFAULT '0' COMMENT '0未签到 1正常 2迟到 3请假',
`location` point DEFAULT NULL,
`create_time` datetime NOT NULL,
PRIMARY KEY (`id`),
SPATIAL KEY `idx_location` (`location`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
3. 核心业务逻辑实现细节
3.1 点名流程时序设计
- 教师创建点名会话:
java复制// AttendanceController.java
@PostMapping("/create")
public Result create(@RequestBody AttendanceDTO dto) {
String qrcode = UUID.randomUUID().toString();
redisTemplate.opsForValue().set(
"rollcall:" + dto.getCourseId(),
qrcode,
10, TimeUnit.MINUTES); // 二维码10分钟有效
return Result.success(qrcode);
}
- 学生扫码提交签到:
javascript复制// 小程序端签到逻辑
wx.scanCode({
success: (res) => {
wx.request({
url: 'https://api.example.com/attendance/checkin',
method: 'POST',
data: {
code: res.result,
location: app.globalData.location
}
})
}
})
3.2 防作弊关键措施
- 地理位置验证:
java复制// 计算两点间距离(米)
public static double getDistance(double lng1, double lat1,
double lng2, double lat2) {
double radLat1 = Math.toRadians(lat1);
double radLat2 = Math.toRadians(lat2);
double a = radLat1 - radLat2;
double b = Math.toRadians(lng1) - Math.toRadians(lng2);
return 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a/2),2) +
Math.cos(radLat1)*Math.cos(radLat2)*Math.pow(Math.sin(b/2),2))) * 6378137;
}
- 二维码时效性控制:
- 每次点名生成唯一二维码
- Redis设置自动过期
- 前端每30秒刷新二维码显示
4. 开发过程中的典型问题与解决方案
4.1 微信小程序兼容性问题
textarea组件margin失效问题:
根本原因是小程序基础库的样式隔离机制。解决方案:
css复制/* 父容器添加overflow属性 */
.container {
overflow: hidden;
}
/* textarea使用固定高度 */
textarea {
height: 200rpx;
margin-top: 20rpx;
}
顶部导航栏高度适配:
javascript复制// 动态获取系统信息
wx.getSystemInfo({
success: function(res) {
const statusBarHeight = res.statusBarHeight
const navHeight = res.platform === 'android' ? 48 : 44
this.setData({
navBarHeight: statusBarHeight + navHeight
})
}
})
4.2 SpringBoot后端性能优化
- 大文件上传处理:
java复制@Bean
public MultipartConfigElement multipartConfigElement() {
MultipartConfigFactory factory = new MultipartConfigFactory();
factory.setMaxFileSize(DataSize.ofMegabytes(50));
factory.setMaxRequestSize(DataSize.ofMegabytes(100));
return factory.createMultipartConfig();
}
- 高频接口缓存策略:
java复制@Cacheable(value = "course", key = "#courseId")
public CourseVO getCourseDetail(Long courseId) {
// 数据库查询逻辑
}
5. 项目部署与运维实践
5.1 Linux环境部署要点
- JDK环境配置:
bash复制# 安装OpenJDK
sudo apt install openjdk-11-jdk
# 设置环境变量
echo 'export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64' >> ~/.bashrc
- SpringBoot应用启动:
bash复制nohup java -jar rollcall-system.jar \
--spring.profiles.active=prod \
> /var/log/rollcall.log 2>&1 &
5.2 监控与日志管理
- 使用Spring Boot Actuator暴露监控端点:
properties复制management.endpoints.web.exposure.include=health,info,metrics
management.endpoint.health.show-details=always
- 日志切割配置(logback-spring.xml):
xml复制<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>logs/application.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>logs/application.%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>30</maxHistory>
</rollingPolicy>
</appender>
6. 项目扩展与二次开发建议
- 智能考勤分析扩展:
- 使用Python集成人脸识别SDK
- 基于历史数据预测缺勤风险学生
- 生成可视化学期考勤热力图
- 微服务化改造方向:
- 将考勤、课程、用户模块拆分为独立服务
- 使用Spring Cloud Alibaba实现服务治理
- 引入RabbitMQ处理异步消息
- 小程序体验优化:
- 实现WebSocket实时推送考勤状态
- 增加LBS围栏签到功能
- 集成语音识别快速点名
这个项目从第一行代码到最终上线历时3个月,期间经历了17次版本迭代。最大的收获是认识到教育信息化产品的核心不是技术复杂度,而是如何用最轻量的方式解决实际教学痛点。比如最初设计的复杂人脸识别签到方案,最终被简化为扫码+地理围栏的方案,反而获得更好的用户体验。
