1. 项目背景与核心需求
高校宿舍管理一直是后勤工作中的重点难点。传统手工分配方式存在效率低下、公平性存疑、资源浪费等问题。我在某高校信息化部门工作期间,曾亲眼目睹每年新生入学前,3名后勤老师需要连续加班两周手工处理5000多名新生的宿舍分配,期间还要应对各种"特殊需求"的干扰。
这个Java+SpringBoot排寝室管理系统正是为解决这些痛点而生。系统需要实现以下核心目标:
- 自动化分配:根据学生专业、班级、生源地等属性自动生成最优分配方案
- 动态调整:支持学生调换、宿舍维修等特殊情况下的灵活调整
- 可视化操作:提供Web端管理界面,降低使用门槛
- 数据统计:生成宿舍使用率、空床位等关键指标报表
2. 技术架构设计
2.1 整体技术选型
采用前后端分离架构,主要技术栈如下:
- 后端:SpringBoot 2.7 + MyBatis-Plus 3.5
- 前端:Vue 3 + Element Plus
- 数据库:MySQL 8.0
- 算法层:贪心算法+权重计算
选择SpringBoot的原因在于其快速开发特性和丰富的starter生态。实测表明,相比传统SSM框架,SpringBoot可使开发效率提升40%以上,特别适合毕业设计这类有时间限制的项目。
2.2 数据库设计要点
核心表结构设计如下:
sql复制CREATE TABLE `student` (
`id` varchar(20) NOT NULL COMMENT '学号',
`name` varchar(50) NOT NULL,
`gender` char(1) NOT NULL,
`college` varchar(50) NOT NULL COMMENT '学院',
`major` varchar(50) NOT NULL COMMENT '专业',
`class` varchar(20) NOT NULL COMMENT '班级',
`hometown` varchar(100) DEFAULT NULL COMMENT '生源地',
`special_needs` text COMMENT '特殊需求'
);
CREATE TABLE `dormitory` (
`id` int NOT NULL AUTO_INCREMENT,
`building` varchar(10) NOT NULL COMMENT '楼栋',
`room` varchar(10) NOT NULL COMMENT '房间号',
`bed_count` int NOT NULL COMMENT '床位数量',
`current_count` int DEFAULT '0' COMMENT '已住人数',
`gender_limit` char(1) NOT NULL COMMENT '性别限制'
);
特别注意的点:
- 性别字段使用char(1)而非varchar,节省存储空间
- 宿舍表设置current_count字段实时统计入住人数
- 建立联合索引(building, room)提升查询效率
3. 核心算法实现
3.1 自动分配算法设计
宿舍分配本质上是个带约束条件的组合优化问题。我们采用改进的贪心算法实现:
java复制public List<Assignment> autoAssign(List<Student> students, List<Dormitory> dorms) {
// 预处理:按专业-班级-生源地分组
Map<String, List<Student>> groups = students.stream()
.collect(Collectors.groupingBy(s ->
s.getMajor() + s.getClass() + s.getHometown()));
// 宿舍按楼栋-房间排序
dorms.sort(Comparator.comparing(Dormitory::getBuilding)
.thenComparing(Dormitory::getRoom));
List<Assignment> result = new ArrayList<>();
for (List<Student> group : groups.values()) {
for (Student student : group) {
Dormitory target = findAvailableDorm(dorms, student.getGender());
if (target != null) {
result.add(new Assignment(student, target));
target.setCurrentCount(target.getCurrentCount() + 1);
}
}
}
return result;
}
算法特点:
- 优先保证同专业同班级学生住在一起
- 考虑生源地分布,避免地域过于集中
- 实时更新宿舍入住状态
3.2 权重计算模型
对于特殊需求(如残疾学生需要低楼层),引入权重计算:
java复制float calculatePriority(Student s, Dormitory d) {
float score = 0;
// 楼层匹配(1层得10分,每高一层减1分)
score += 10 - Integer.parseInt(d.getFloor());
// 同专业同学加分
if (d.getStudents().stream().anyMatch(x -> x.getMajor().equals(s.getMajor()))) {
score += 5;
}
// 特殊需求处理
if (s.getSpecialNeeds() != null) {
if (s.getSpecialNeeds().contains("轮椅") && d.getFloor().equals("1")) {
score += 20;
}
}
return score;
}
4. 系统功能实现
4.1 后端关键接口
- 分配接口:
java复制@PostMapping("/assign")
public Result autoAssign(@RequestParam(required = false) String batchId) {
List<Student> unassigned = studentService.getUnassignedStudents();
List<Dormitory> available = dormService.getAvailableDorms();
List<Assignment> assignments = assignService.autoAssign(unassigned, available);
return Result.success(assignments);
}
- 调换接口:
java复制@PostMapping("/swap")
public Result swapBed(@Valid @RequestBody SwapRequest request) {
// 验证两个床位是否同性别
if (!bedService.checkGenderMatch(request.getBed1(), request.getBed2())) {
return Result.error("性别不匹配");
}
assignmentService.swap(request);
return Result.success();
}
4.2 前端实现技巧
使用Element Plus实现的可视化分配面板:
vue复制<template>
<el-draggable
v-model="unassignedStudents"
group="students"
@end="onDragEnd">
<div v-for="s in unassignedStudents" :key="s.id" class="student-card">
{{ s.name }} ({{ s.major }})
</div>
</el-draggable>
<div v-for="d in dormitories" class="dorm-room">
<div class="bed" v-for="b in d.beds" @drop="onDrop($event, b)">
{{ b.number }}
</div>
</div>
</template>
5. 部署与优化
5.1 性能优化方案
- 缓存策略:
java复制@Cacheable(value = "dorms", key = "#gender")
public List<Dormitory> getAvailableDormsByGender(String gender) {
return mapper.selectList(
new QueryWrapper<Dormitory>()
.eq("gender_limit", gender)
.lt("current_count", bed_count));
}
- 批量插入优化:
java复制@Transactional
public void batchAssign(List<Assignment> assignments) {
// 使用MyBatis-Plus的saveBatch方法
assignmentService.saveBatch(assignments);
// 使用UPDATE CASE语句一次性更新宿舍状态
dormMapper.batchUpdateCount(assignments);
}
5.2 安全防护措施
- 数据权限控制:
java复制@PreAuthorize("hasRole('DORM_ADMIN') or #college == authentication.principal.college")
public List<Dormitory> getDormsByCollege(String college) {
return dormMapper.selectByCollege(college);
}
- 操作日志记录:
java复制@Aspect
@Component
public class LogAspect {
@AfterReturning(pointcut = "@annotation(operationLog)", returning = "result")
public void afterReturning(JoinPoint jp, OperationLog operationLog, Object result) {
String operation = operationLog.value();
logService.save(operation, getUser(), getIp());
}
}
6. 常见问题与解决方案
6.1 分配结果不均衡问题
现象:某些宿舍入住率明显低于平均水平
解决方案:
- 在算法中加入宿舍填充度权重:
java复制float fillFactor = 1 + (d.getCurrentCount() / (float)d.getBedCount());
score *= fillFactor; // 优先选择入住率低的宿舍
- 设置最大差异阈值,当差异超过20%时触发二次分配
6.2 并发修改冲突
现象:多人同时操作导致数据不一致
解决方案:
- 使用乐观锁控制:
java复制@Update("UPDATE dormitory SET current_count = current_count + 1
WHERE id = #{id} AND current_count < bed_count")
int tryOccupyBed(@Param("id") Long id);
- 前端加入操作锁提示:
vue复制<el-button :disabled="isOperating" @click="handleAssign">
{{ isOperating ? '处理中...' : '开始分配' }}
</el-button>
7. 项目扩展方向
- 微信小程序端:学生可查看宿舍信息、提交调换申请
- 智能电表对接:实时监测宿舍用电情况
- 人脸识别门禁:与宿舍管理系统联动
- 行为分析:基于出入记录分析异常情况
关键提示:毕业设计答辩时,建议重点展示算法设计部分和性能优化方案,这是最能体现技术深度的环节。同时准备几组测试数据,现场演示分配效果对比。