1. 项目背景与核心需求
舞蹈培训机构在数字化浪潮中面临诸多运营痛点:学员信息分散在Excel表格中、课程安排依赖人工排班、财务收支记录混乱、教师与学员沟通不畅。传统管理方式已无法满足现代艺术培训机构高效运营的需求。
这个SpringBoot舞蹈室管理系统正是为解决这些实际问题而设计。我在实际开发中发现,一套好的管理系统需要同时满足三个维度的需求:
- 机构运营者:需要清晰的财务数据、便捷的排课工具和精准的学员分析
- 舞蹈教师:需要直观的课表查看、学员考勤记录和教学进度管理
- 学员家长:需要透明的课程消费、方便的约课渠道和及时的通知提醒
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 系统架构设计
2.1 技术选型决策
选择SpringBoot作为基础框架基于以下考量:
- 快速开发特性:内嵌Tomcat、自动配置让项目能快速启动
- 微服务友好:便于后期扩展为多校区管理系统
- 丰富的starter:整合MyBatis、Redis等组件非常便捷
技术栈组成:
- 前端:Thymeleaf + Bootstrap(考虑培训机构管理员通常非技术背景)
- 持久层:MyBatis-Plus + PageHelper分页插件
- 缓存:Redis存储高频访问的课表数据
- 安全:Spring Security + JWT实现多角色权限控制
2.2 数据库设计要点
核心表结构设计时特别注意了舞蹈培训特有的业务场景:
sql复制CREATE TABLE `course_schedule` (
`id` bigint NOT NULL AUTO_INCREMENT,
`studio_id` int NOT NULL COMMENT '舞蹈室ID',
`teacher_id` int NOT NULL,
`course_type` varchar(20) NOT NULL COMMENT '课程类型:少儿/成人/私教',
`start_time` datetime NOT NULL COMMENT '实际考虑舞蹈课多在晚间周末',
`duration` int NOT NULL COMMENT '课时长(分钟)',
`max_students` int DEFAULT '12' COMMENT '小班制限额',
`status` tinyint DEFAULT '0' COMMENT '0未开始 1进行中 2已取消',
PRIMARY KEY (`id`),
KEY `idx_time_room` (`studio_id`,`start_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
特别注意的字段设计:
- 课程类型区分少儿/成人班,后续统计营收时需要按类型分析
- 课时长精确到分钟而非小时,适应不同舞蹈种类的课时差异
- 状态字段包含"已取消"状态,记录调课历史
3. 核心功能实现
3.1 智能排课算法
舞蹈室排课面临三大难题:
- 教师可用时间不固定(兼职教师常见)
- 舞蹈室资源有限(特别是镜房、把杆等专业设施)
- 学员偏好时段集中(晚间和周末)
实现方案:
java复制public List<ScheduleConflict> checkConflict(ScheduleDTO dto) {
// 检查教室占用冲突
List<CourseSchedule> roomSchedules = scheduleMapper.selectByRoomAndTime(
dto.getStudioId(),
dto.getStartTime(),
dto.getEndTime());
// 检查教师时间冲突
List<CourseSchedule> teacherSchedules = scheduleMapper.selectByTeacherAndTime(
dto.getTeacherId(),
dto.getStartTime(),
dto.getEndTime());
return mergeConflicts(roomSchedules, teacherSchedules);
}
排课时的特殊处理:
- 预留至少15分钟课间时间(实测发现少于15分钟会导致连续课程间的混乱)
- 自动避开法定节假日(通过集成第三方节假日API)
- 支持"试听课"特殊标记(不计入教师课时统计)
3.2 学员考勤的RFID解决方案
传统签到方式的问题:
- 纸质签到易丢失、难统计
- 手机扫码签到对少儿学员不友好
我们采用的RFID卡方案实施细节:
- 硬件选型:选用13.56MHz频段的MIFARE Classic卡(成本约3元/张)
- 读卡器接入:通过USB转串口连接,Java使用RXTX库通信
- 考勤逻辑:
java复制public AttendanceResult handleRFID(String cardId) {
// 1. 查询当前有效课程
CourseSchedule currentCourse = getCurrentCourse();
// 2. 验证学员是否报名本课程
Enrollment enrollment = enrollmentMapper.selectByCourseAndCard(
currentCourse.getId(),
cardId);
// 3. 记录考勤(考虑迟到情况)
if(enrollment != null) {
AttendanceRecord record = new AttendanceRecord();
record.setArrivalTime(LocalDateTime.now());
record.setStatus(calculateLateStatus(currentCourse));
attendanceMapper.insert(record);
return AttendanceResult.success(record);
}
return AttendanceResult.fail("未报名本课程");
}
实施中发现的关键点:
- RFID卡需要做防冲突处理(特别是下课集中刷卡时)
- 需要定期清理读卡器缓存(实测超过200条未处理记录会导致阻塞)
- 家长关联卡设计:一张主卡可关联多张副卡供不同家庭成员使用
4. 特色功能实现
4.1 教学视频点播系统
舞蹈培训机构积累了大量教学视频资源,但存在:
- 视频分散在各个教师电脑中
- 缺乏分类和搜索功能
- 没有观看进度记录
我们的解决方案架构:
code复制用户层:WEB/APP点播界面
↓
应用层:SpringBoot视频服务(含断点续传、多码率支持)
↓
存储层:MinIO分布式存储(替代FastDFS更易维护)
↓
处理层:FFmpeg转码集群(生成HLS流)
关键代码示例(视频分片上传):
java复制@PostMapping("/chunk-upload")
public ResponseEntity<?> chunkUpload(
@RequestParam MultipartFile file,
@RequestParam String chunkNumber,
@RequestParam String identifier) {
// 临时目录按文件标识符创建
String tempDir = "/tmp/upload/" + identifier;
File dir = new File(tempDir);
if (!dir.exists()) dir.mkdirs();
// 保存分片
String chunkFilename = chunkNumber + ".part";
file.transferTo(new File(dir, chunkFilename));
// 检查是否所有分片已上传(前端需预传总片数)
if (isUploadComplete(dir)) {
mergeChunks(dir, identifier);
return ResponseEntity.ok().build();
}
return ResponseEntity.accepted().build();
}
实际运营中的经验:
- 少儿舞蹈视频需要额外存储低清版本(家长常在外用移动网络观看)
- 转码预设参数要针对舞蹈视频优化(保留更多动态细节)
- 热门视频需要做CDN预热(特别是考级课程视频)
4.2 财务对账模块
舞蹈培训的财务特点:
- 收费模式多样(次卡/月卡/年卡/私教包)
- 存在多人拼团、老带新优惠等营销活动
- 需要按教师、课程类型等多维度分成
财务对账核心逻辑:
java复制public void generateDailyReport(LocalDate date) {
// 1. 获取当日所有交易
List<PaymentRecord> payments = paymentMapper.selectByDate(date);
// 2. 按支付渠道分类统计
Map<String, BigDecimal> channelSummary = payments.stream()
.collect(Collectors.groupingBy(
PaymentRecord::getChannel,
Collectors.reducing(
BigDecimal.ZERO,
PaymentRecord::getAmount,
BigDecimal::add)));
// 3. 生成教师课时费(考虑不同课程类型提成比例)
List<TeacherSettlement> teacherStats = calculateTeacherFee(payments);
// 4. 持久化报表
DailyReport report = assembleReport(date, channelSummary, teacherStats);
reportMapper.insert(report);
}
特别注意的处理:
- 退款需要关联原订单逆向处理(不能简单记为负收入)
- 套餐卡需要按次核销(记录每次扣减的剩余次数)
- 优惠活动需要单独标记(评估营销活动ROI)
5. 部署与性能优化
5.1 生产环境部署方案
推荐部署架构:
code复制 +-----------------+
| 阿里云SLB |
+--------+--------+
|
+----------------+----------------+
| |
+----------+----------+ +----------+----------+
| Nginx (静态资源) | | Nginx (API网关) |
+----------+----------+ +----------+----------+
| |
+----------+----------+ +----------+----------+
| 视频存储节点 | | SpringBoot应用集群 |
+---------------------+ +----------+----------+
|
+-----------+-----------+
| Redis |
+-----------+-----------+
|
+-----------+-----------+
| MySQL集群 |
+---------------------+
关键配置项(application-prod.yml):
yaml复制spring:
datasource:
hikari:
maximum-pool-size: 20
connection-timeout: 30000
redis:
lettuce:
pool:
max-active: 50
max-wait: 10000
server:
tomcat:
max-threads: 200
accept-count: 100
5.2 性能优化实战记录
- 课表查询优化:
- 原方案:每次请求查询数据库 → 平均响应800ms
- 优化后:Redis缓存未来7天课表 + 本地缓存当天课表 → 响应<50ms
- 并发报名处理:
java复制@Transactional
public boolean enrollCourse(Long courseId, Long studentId) {
// 使用SELECT...FOR UPDATE锁定课程记录
CourseSchedule course = scheduleMapper.selectForUpdate(courseId);
if (course.getRegistered() >= course.getMaxStudents()) {
throw new BusinessException("课程已满");
}
// 验证学员剩余课时是否足够
Integer remaining = accountMapper.selectRemainingClasses(studentId);
if (remaining == null || remaining <= 0) {
throw new BusinessException("课时不足");
}
// 创建报名记录
Enrollment enrollment = new Enrollment();
enrollment.setCourseId(courseId);
enrollment.setStudentId(studentId);
enrollmentMapper.insert(enrollment);
// 更新课程报名人数
scheduleMapper.incrementRegistered(courseId);
// 扣除课时
accountMapper.decrementClasses(studentId);
return true;
}
- 监控方案实施:
- 使用Spring Boot Actuator暴露健康指标
- Prometheus采集JVM/数据库指标
- Grafana展示关键业务指标(每日新增学员、课程饱和度等)
6. 项目演进方向
在实际运营中收集的用户反馈显示,以下几个扩展方向值得关注:
- 移动端深化:
- 开发微信小程序版本(家长使用频率最高)
- 增加视频打卡功能(学员上传练习视频)
- 集成在线支付(支持花呗分期等付款方式)
- 智能推荐:
- 基于学员年龄/基础推荐适合课程
- 根据出勤率预测续费意愿
- 教师时间安排的智能建议
- 硬件集成:
- 舞蹈室智能门禁(关联课程预约)
- 体感设备数据采集(评估动作标准度)
- 能耗管理系统(镜前灯、空调的智能控制)
这套系统在三个不同规模的舞蹈机构(50-200学员量级)实际运行6个月后,帮助机构平均提升运营效率约40%,减少约25%的行政人力成本。特别是自动化的财务对账和智能排课功能,获得了机构管理者的一致好评。
