高校宿舍管理一直是校园后勤工作的重点难点。传统纸质登记、Excel表格统计的方式效率低下,信息更新滞后,查寝结果难以及时同步,学生报修流程繁琐。基于SpringBoot和小程序的高校宿舍管理系统,正是为解决这些痛点而生。
这个系统将宿舍分配、卫生检查、设备报修、访客登记等高频场景全部线上化。学生通过微信小程序即可完成各类申请和查询,宿管人员通过后台管理系统实时处理业务。我去年在某职业技术学院落地过类似项目,上线后宿舍相关事务处理效率提升60%以上,学生满意度调查显示报修响应速度从原来的平均3天缩短到8小时内。
采用SpringBoot + Uni-app前后端分离架构。后端选用SpringBoot 2.7.x版本,主要考虑其:
数据库使用MySQL 8.0,主要优势:
小程序端选择Uni-app而非原生开发,因为:
系统主要包含6个核心模块:
采用unionId作为用户唯一标识是关键。具体实现流程:
java复制// 后端登录接口核心代码
@PostMapping("/wxLogin")
public Result wxLogin(@RequestBody LoginDTO dto) {
// 1. 调用微信接口获取session_key
String url = "https://api.weixin.qq.com/sns/jscode2session?appid="
+ appId + "&secret=" + appSecret + "&js_code=" + dto.getCode() + "&grant_type=authorization_code";
WxAuthResponse response = restTemplate.getForObject(url, WxAuthResponse.class);
// 2. 解密获取用户信息
String decryptData = decrypt(dto.getEncryptedData(), response.getSession_key(), dto.getIv());
WxUserInfo userInfo = JSON.parseObject(decryptData, WxUserInfo.class);
// 3. 绑定或创建用户
User user = userService.getByUnionId(userInfo.getUnionId());
if(user == null) {
user = new User();
BeanUtils.copyProperties(userInfo, user);
userService.save(user);
}
// 4. 生成JWT令牌
String token = JwtUtil.generateToken(user.getId(), user.getRole());
return Result.success(token);
}
特别注意:小程序获取手机号需要企业认证,很多高校项目卡在这个环节。建议前期先用微信昵称+学号验证的方式过渡。
核心是解决新生批量分配时的多约束条件问题。我们设计的算法考虑:
具体实现采用权重评分法:
java复制public List<Student> autoAssign(List<Student> students) {
// 1. 预处理:按专业班级分组
Map<String, List<Student>> groupMap = students.stream()
.collect(Collectors.groupingBy(s -> s.getMajor() + "_" + s.getClassNo()));
// 2. 为每个宿舍计算适配度
List<Dorm> dorms = dormService.getAvailableDorms();
for (Dorm dorm : dorms) {
for (String key : groupMap.keySet()) {
List<Student> group = groupMap.get(key);
// 计算该宿舍当前专业分布情况
long sameMajorCount = dorm.getStudents().stream()
.filter(s -> s.getMajor().equals(group.get(0).getMajor()))
.count();
// 计算权重得分
double score = sameMajorCount * 0.6
+ (4 - dorm.getStudents().size()) * 0.3
+ (dorm.getBuilding().equals(group.get(0).getPreferBuilding()) ? 0.1 : 0);
dorm.setScore(score);
}
}
// 3. 分配实现(简化版)
return assignByScore(students, dorms);
}
工单状态流转是报修模块的核心,我们采用状态模式实现:
java复制public interface RepairState {
void handle(RepairOrder order);
}
@Component
@Scope("prototype")
public class PendingState implements RepairState {
@Override
public void handle(RepairOrder order) {
if ("ASSIGN".equals(order.getAction())) {
order.setState(new AssignedState());
// 发送微信通知维修人员
wxNoticeService.sendRepairAssignNotice(order);
}
}
}
// 其他状态:AssignedState/ProcessingState/CompletedState等
// 使用示例
public void changeState(Long orderId, String action) {
RepairOrder order = repairOrderMapper.selectById(orderId);
RepairState state = (RepairState) applicationContext
.getBean(order.getStatus().toLowerCase() + "State");
state.handle(order);
repairOrderMapper.updateById(order);
}
宿舍报修场景中,学生上传损坏设备照片是高频操作。我们做了以下优化:
关键配置示例:
properties复制# application.properties
cos.secretId=您的SecretId
cos.secretKey=您的SecretKey
cos.region=ap-shanghai
cos.bucketName=your-bucket-name
cos.thumb.width=200
cos.thumb.height=200
卫生检查场景需要批量导入Excel数据,采用EasyExcel解决内存问题:
java复制@PostMapping("/import")
public void importExcel(@RequestParam("file") MultipartFile file) {
EasyExcel.read(file.getInputStream(), CheckRecord.class, new PageReadListener<CheckRecord>(dataList -> {
// 批量处理每100条数据
checkService.batchSave(dataList);
})).sheet().doRead();
}
// 批量插入使用MyBatis的foreach标签
<insert id="batchInsert" parameterType="java.util.List">
INSERT INTO check_record(dorm_id, inspector, score)
VALUES
<foreach collection="list" item="item" separator=",">
(#{item.dormId}, #{item.inspector}, #{item.score})
</foreach>
</insert>
报修完成后支付押金是常见场景,回调处理要点:
回调接口示例:
java复制@PostMapping("/pay/callback")
public String callback(HttpServletRequest request) {
// 1. 获取通知数据
String xmlData = IOUtils.toString(request.getInputStream(), StandardCharsets.UTF_8);
// 2. 验证签名
if (!WxPayUtil.isSignatureValid(xmlData, apiKey)) {
return "<xml><return_code><![CDATA[FAIL]]></return_code></xml>";
}
// 3. 处理业务
WxPayOrderNotifyResult result = WxPayOrderNotifyResult.deserialize(xmlData);
if ("SUCCESS".equals(result.getResultCode())) {
repairOrderService.handlePaySuccess(result.getOutTradeNo());
}
return "<xml><return_code><![CDATA[SUCCESS]]></return_code></xml>";
}
新生入学时集中分配宿舍容易产生并发问题,解决方案:
sql复制UPDATE dorm SET remain_beds = remain_beds - 1
WHERE id = #{dormId} AND remain_beds > 0
java复制public boolean assignBed(Long dormId, Long studentId) {
String lockKey = "dorm:assign:" + dormId;
try {
// 尝试获取锁,设置10秒过期
Boolean locked = redisTemplate.opsForValue()
.setIfAbsent(lockKey, "1", 10, TimeUnit.SECONDS);
if (locked != null && locked) {
return dormService.doAssign(dormId, studentId);
}
return false;
} finally {
redisTemplate.delete(lockKey);
}
}
根据高校规模推荐配置:
必须监控的关键指标:
小程序端:
服务端:
配置Prometheus监控示例:
yaml复制# prometheus.yml
scrape_configs:
- job_name: 'springboot'
metrics_path: '/actuator/prometheus'
static_configs:
- targets: ['localhost:8080']
已落地项目可以考虑以下扩展:
我在某高校项目中尝试过智能电表对接,发现几个实用技巧: