1. 项目背景与核心需求
在教育机构日常运营中,课外兴趣班和延时班的管理一直是教务工作的重点难点。传统的手工登记、Excel表格管理方式存在数据分散、统计困难、家校沟通不畅等问题。我们团队为某连锁教育机构开发的这套管理系统,正是为了解决以下痛点:
- 课程安排冲突:手工排课经常出现教师时间冲突、教室资源冲突
- 报名统计滞后:家长通过纸质或微信报名,数据需要人工汇总
- 考勤效率低下:课时消耗统计依赖教师手工记录
- 家校互动缺失:家长无法实时查看孩子上课情况
系统采用SpringBoot+Vue的前后端分离架构,经过三个月的开发和两个月的试运行,目前已在12个校区稳定运行,日均处理3000+条业务数据。下面从技术实现角度分享关键设计思路。
2. 技术架构设计
2.1 整体架构方案
系统采用经典的三层架构:
code复制前端(Vue) ←HTTP→ 后端(SpringBoot) ←JDBC→ 数据库(MySQL)
技术选型理由:
- Vue 2.x:考虑到团队技术储备和生态成熟度,未采用Vue3
- Element UI:表单密集的管理系统需要成熟的UI组件库
- SpringBoot 2.5.4:长期支持版本,与生产环境JDK8兼容
- MySQL 5.7:事务处理性能满足高并发报名场景
2.2 前后端交互设计
采用RESTful API规范设计接口,关键配置示例:
java复制// SpringBoot跨域配置
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedMethods("GET", "POST", "PUT", "DELETE")
.maxAge(3600);
}
}
前端axios封装:
javascript复制// src/utils/request.js
const service = axios.create({
baseURL: process.env.VUE_APP_BASE_API,
timeout: 5000
})
// 请求拦截器
service.interceptors.request.use(
config => {
if (store.getters.token) {
config.headers['X-Token'] = getToken()
}
return config
},
error => {
return Promise.reject(error)
}
)
3. 核心功能实现
3.1 智能排课算法
排课模块采用贪心算法+冲突检测机制:
- 优先安排限定条件多的课程(如外教固定时间)
- 检测教师时间窗口冲突
- 检测教室资源占用冲突
核心代码结构:
java复制public class ScheduleService {
// 冲突检测方法
private boolean checkConflict(ScheduleDTO newSchedule) {
// 检查教师时间
int teacherCount = scheduleMapper.countByTeacherAndTime(
newSchedule.getTeacherId(),
newSchedule.getStartTime(),
newSchedule.getEndTime());
// 检查教室时间
int roomCount = scheduleMapper.countByRoomAndTime(
newSchedule.getRoomId(),
newSchedule.getStartTime(),
newSchedule.getEndTime());
return teacherCount > 0 || roomCount > 0;
}
// 贪心排课入口
public List<ScheduleVO> generateSchedule(ScheduleQuery query) {
// 实现略...
}
}
3.2 实时考勤统计
采用WebSocket实现考勤数据实时推送:
javascript复制// 前端考勤组件
created() {
this.socket = new WebSocket(`wss://${location.host}/ws/attendance`)
this.socket.onmessage = (event) => {
const data = JSON.parse(event.data)
this.updateAttendance(data)
}
}
后端事件处理:
java复制@RestController
public class AttendanceController {
@Autowired
private SimpMessagingTemplate messagingTemplate;
@PostMapping("/checkin")
public Result checkIn(@RequestBody CheckInDTO dto) {
// 保存考勤记录
attendanceService.saveRecord(dto);
// 推送实时数据
messagingTemplate.convertAndSend(
"/topic/attendance",
statsService.getRealTimeStats());
return Result.success();
}
}
4. 关键问题解决方案
4.1 高并发报名处理
报名高峰期出现的问题:
- 热门课程瞬间超卖
- 数据库更新丢失
- 系统响应变慢
解决方案:
- 使用Redis分布式锁:
java复制public boolean lock(String key, long expire) {
String lockKey = "lock:" + key;
return redisTemplate.opsForValue()
.setIfAbsent(lockKey, "1", expire, TimeUnit.SECONDS);
}
- 数据库乐观锁:
sql复制UPDATE course SET remain = remain - 1
WHERE id = #{id} AND remain >= 1
- 前端限流控制:
javascript复制// 提交按钮节流
submitBtn.addEventListener('click', _.throttle(() => {
submitForm();
}, 1000));
4.2 大数据量导出优化
成绩单导出时内存溢出问题:
- 使用POI的SXSSFWorkbook模式
- 分页查询+流式处理
- 后端压缩传输
核心代码:
java复制@GetMapping("/export")
public void exportReport(HttpServletResponse response) {
// 设置流式导出
SXSSFWorkbook workbook = new SXSSFWorkbook(100); // 保留100行在内存
// 分页查询数据
int pageSize = 1000;
for (int page = 1; ; page++) {
List<Record> records = findPage(page, pageSize);
if (records.isEmpty()) break;
// 写入当前页数据
writeToSheet(workbook, records);
}
// 压缩输出
response.setHeader("Content-Encoding", "gzip");
try (GZIPOutputStream gzipOut = new GZIPOutputStream(response.getOutputStream())) {
workbook.write(gzipOut);
}
}
5. 部署与运维实践
5.1 前端部署方案
采用Nginx+Docker部署模式:
dockerfile复制# Dockerfile
FROM nginx:alpine
COPY dist/ /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
Nginx关键配置:
nginx复制server {
listen 80;
location / {
try_files $uri $uri/ /index.html;
}
location /api {
proxy_pass http://backend:8080;
}
}
5.2 性能监控方案
使用SpringBoot Actuator+Prometheus+Grafana搭建监控看板:
- 添加依赖:
xml复制<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
- 配置端点:
yaml复制management:
endpoints:
web:
exposure:
include: health,metrics,prometheus
metrics:
tags:
application: ${spring.application.name}
6. 项目演进方向
目前系统已在以下方面进行迭代:
- 微信小程序端:使用uni-app重构部分前端,支持家长微信端操作
- 智能推荐:基于历史数据的课程推荐算法
- 语音通知:集成阿里云语音服务发送上课提醒
典型的功能扩展代码示例:
javascript复制// 微信JS-SDK集成
wx.config({
debug: false,
appId: '', // 公众号AppID
timestamp: '',
nonceStr: '',
signature: '',
jsApiList: ['chooseImage', 'previewImage']
})
wx.ready(() => {
this.wechatReady = true
})
在开发过程中,我们特别注重以下实践原则:
- 所有API接口必须提供Swagger文档
- 前端组件按功能域划分目录结构
- 数据库变更必须通过Flyway管理
- 关键业务操作记录审计日志
这套系统从技术实现角度看,体现了现代Web开发的典型技术组合。在实际运行中,最大的收获是认识到:教育行业的业务复杂性往往超出预期,良好的领域建模和适度的技术方案才是项目成功的关键。
