首页 / 资讯中心 / 文章详情

基于Spring Boot与微信小程序的宿舍管理系统开发实战

基于Spring Boot与微信小程序的宿舍管理系统开发实战 ★ FEATURED ARTICLE
1. 先盘清楚需求宿舍管理到底管理哪些事做这个玉林师范学院宿舍管理系统之前我大概花了整整一周时间泡在宿舍楼里跟宿管阿姨聊天、看登记本、观察学生的日常流程。很多人觉得宿舍管理系统无非就是登记一下入住、退宿再搞个报修功能真做起来才发现完全不是这么回事。一个普通的学生宿舍楼日常涉及的角色就有学生、宿管员、辅导员、维修工、后勤管理员每个角色的痛点和诉求都不一样。先说学生这边他们最关心三件事——新生入学怎么快速知道自己住哪栋哪间哪张床宿舍里东西坏了灯不亮、门锁坏、水管漏水怎么报修、多久有人来修以及换宿舍、退宿舍这种流程能不能少跑几趟。宿管阿姨的痛点就现实多了纸质登记表翻起来费劲查晚归要一页页对名单学生毕业退宿时要上楼一间间检查家具损坏情况。她最希望的是有个能按楼栋、按楼层、按宿舍号快速检索的电子台账谁住了谁、谁搬走了、哪间空着一眼就能看清楚。辅导员的角度又不一样。他们要关注学生在校情况哪个床位空出来了可以安排新学生入住哪个学生长期不在宿舍住需要留意还有每学期宿舍卫生评比的底稿从哪来。后勤管理和维修工在乎的是报修工单的流转效率。一个报修单从提交到派单、接单、完成、验收如果全靠口头传达大概率会出“学生报了三天没人修”的情况最后闹到校长信箱。所以我在梳理需求时把整个系统分成了这么几大块基础信息管理楼栋、房间、床位、院系、班级、学生入住与退宿管理、调宿换宿流程、日常报修管理系统、查寝与晚归记录、宿舍卫生评比以及面向管理决策的数据统计可视化。这里面入住退宿和报修是优先级最高的两条主线数据可视化是加分项但也是答辩时最能体现系统价值的部分。还有一个容易被忽略的点宿舍管理不是孤立的它跟学生基本信息学号、姓名、班级、辅导员、缴费信息住宿费、水电费都有联动。虽然很多人会把宿舍、教务、财务几个系统分开做但在毕业设计这个体量里宿舍系统至少要预留出关联字段否则后面扩展数据可视化报表的时候会非常痛苦。明确完需求边界我再补充一点选型层面的判断。这套系统的前台展示我最终用了微信小程序后台管理用Web页面后端统一走Java技术栈。为什么没做原生App因为高校场景下学生换手机频率高、系统碎片化严重iOS和Android两套都要维护成本太高小程序“用完即走”的属性更贴合学生偶尔报修、查宿舍号的低频使用习惯。这是我在后面章节会详细展开的取舍逻辑。2. Spring Boot 后台 小程序前端技术选型背后的取舍2.1 后台技术栈为什么锁定 Java 系技术选型永远是做项目的第一步也最容易被忽视。很多人上来就写代码写到一半发现框架不适合、数据库设计不合理再回头改成本巨大。我当时选型是认真对比过的纯Servlet的JSP老项目、Spring Boot、PHP、Python Flask/Django甚至想过用C#或C来做底层服务但最终全部放弃锁定了Spring Boot MyBatis的组合。原因有几点。第一是生态成熟度。Spring Boot 对 REST API、拦截器、事务管理、定时任务的支持非常完善这些恰恰是宿舍管理系统用得最多的能力。报修工单的状态流转要开事务每天凌晨自动更新宿舍入住状态要开定时任务接口鉴权要拦截器这些都是Spring Boot的舒适区。第二是团队协作和维护方便。虽然这个项目是我一个人从零写的但考虑到答辩时老师可能要跑起来看、后续如果有学弟学妹接手Java系代码的可读性和社区资料丰富程度远胜PHP和C。尤其是MyBatis我可以用XML维护复杂的SQL比如“查询当前所有有空床位的宿舍并按楼栋分组”这种SQL用MyBatis写出来非常直观后期调优也好定位问题。第三是部署环境匹配。学校机房和实验室里的服务器大多是Windows/Linux双系统JDK Maven MySQL这套环境一套就熟而PHP虽然部署简单但面对复杂业务逻辑时框架约束力不如Spring BootPython写小工具确实快但做大型业务系统在工程化方面还是稍弱。这里我要多说一句关于C#和C的问题。热词里出现了C#、C确实有不少人问为什么不选择这两个。我的看法是C#在Windows生态下做桌面应用很强但在Linux服务器部署时远不如Java顺手C则更适合底层系统和高性能服务用来做业务管理系统属于大材小用开发效率反而不高。如果你的答辩老师问“为什么不用其他语言”你就从维护成本、生态、部署便捷性三个角度回答比较有说服力。2.2 前端分两端管理后台走Web学生端走小程序前端我做了两个端管理后台与学生小程序。管理后台面向宿管和辅导员用在电脑浏览器上打开操作特点是表格密集、数据量大需要快速筛选和批量操作。这个小程序端做起来很吃力因为小程序的表格组件能力有限左滑删除、批量勾选这些交互需要自己写一大堆代码体验还比不上网页。所以管理后台我选择了Vue Element UI的组合表格、弹窗、表单组件开箱即用省下来的时间都投给了业务逻辑。学生端则选了微信小程序。为什么是小程序而不是H5最关键的因素是身份识别。大学场景里学生身份需要与学号绑定而微信小程序可以通过微信授权拿到学生的OpenID再跟学号进行绑定实现“一次绑定后续免登录”。这个体验比H5需要反复输入账号密码好得多。我给的方案是小程序调用wx.login获取临时code后端拿code到微信接口换OpenID第一次进入小程序时让学生绑定学号和姓名系统校验通过后存到用户表后面所有操作都基于这个绑定关系。小程序端我做了三个核心页面模块首页可以看到我的住宿信息、提交报修、查看公告、报修模块提交、进度、历史记录、个人信息和宿舍绑定。开发时用原生微信小程序框架没有引入uni-app或Taro因为项目复杂度不高原生框架的文档和社区资源最直接踩坑了也容易搜到答案。2.3 Python 和爬虫在这个项目里的真实角色这里我必须泼一盆冷水如果你的毕业设计只是为了做一个宿舍管理系统Python爬虫和它没有半毛钱关系。但是如果你像我一样想做数据可视化大屏Python 可以作为数据预处理工具派上用场。我做数据看板时遇到了一个很现实的问题宿舍管理系统上线前数据库里几乎没有历史数据。没有数据统计图就是空的图表展示的效果就会大打折扣。这时候我用Python写了一个模拟数据生成脚本基于Faker库生成过去一年的学生入住记录、报修工单、晚归记录然后通过MyBatis的对应表结构批量插入MySQL。这样可视化大屏上就有了足够的时间趋势图、宿舍利用率分布图、报修类型饼图。当然这里要声明模拟数据只是为了演示系统的可视化能力不代表真实数据。如果你在做真实的宿舍管理系统初期可以用迁移工具把Excel里的历史台账导入MySQLPython的pandas库是最合适的工具。这个场景才是Python与宿舍系统结合的正当理由而不是去爬什么网站。3. 数据库建模床位、入住与报修三个核心数据链3.1 关系模型的核心思路宿舍管理系统的数据库设计难点不在于表多而在于状态转换的建模。我最终设计的核心表有楼栋表、房间表、床位表、学生用户表、入住记录表、调宿记录表、退宿记录表、报修单表、维修工单表、晚归记录表。一共11张业务表加上权限相关的用户角色表总共14张左右。这里最关键的设计决策是床位表独立成一张表而不是作为房间表的字段。很多新手会把“6人间”设计成房间表里有个bed_count整数入住时再往入住表里加记录。但这样做床位状态查询会非常痛苦想知道某房间还有几个空位得先查入住记录再减掉而且不能区分具体是哪个床位空着。把床位独立成表后每个房间在初始化时生成6条床位记录每条记录有bed_status字段空闲/已入住/维修中/停用查询空床就是一条简单的SELECT。房间表、楼栋表的关系也很清晰楼栋1对多房间房间1对多床位。每张床位表里冗余了dorm_building_id和dorm_room_id查询时虽然有点冗余但可以避免大量的连表操作。3.2 入住退宿流程的状态机设计宿舍管理本质上是一个状态机床位从空闲变成已入住中间经过申请、审核、确认几个环节退宿则从已入住变回空闲中间有申请、宿管确认、家具检查几个环节。如果用散落的if-else来管理这些状态代码很快就会乱成一锅粥。我设计了一张统一的入住记录表关键字段如下CREATE TABLE checkin_record ( id BIGINT AUTO_INCREMENT PRIMARY KEY, student_id BIGINT NOT NULL COMMENT 学生用户ID, bed_id BIGINT NOT NULL COMMENT 床位ID, room_id BIGINT NOT NULL, building_id BIGINT NOT NULL, checkin_date DATE NOT NULL, checkout_date DATE NULL, status TINYINT NOT NULL DEFAULT 1 COMMENT 1在住 2已退 3调宿中, operator_id BIGINT DEFAULT NULL COMMENT 操作人, create_time DATETIME DEFAULT CURRENT_TIMESTAMP, update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP );在“在住”状态下学生还可以发起调宿申请这个动作做的事情本质上就是旧床位释放、新床位占用、入住记录状态改成“已调宿”并关联一条新的入住记录。我把它封装成一个Transactional事务方法避免了数据库更新一半崩溃导致的数据不一致问题。退宿时的家具检查是我特别做的表单逻辑。宿管在后台勾选“完好/有损坏”如果选了损坏系统自动生成一条赔偿记录跟学生的离校手续关联。这么做是为了贴合真实的高校宿舍管理流程答辩的时候可以拿出完整的业务闭环。3.3 报修工单的表设计报修工单几乎是宿舍系统里使用频率最高的功能模拟数据里报修单数量占了很大比重。它的表设计需要支持不同角色对同一张单子的状态更新学生提交、宿管派单、维修工接单、维修完成、学生验收、学生评价。我用了两张表报修单表和处理记录表。报修单表存的是当前状态和静态信息谁报的、什么位置、什么类型、描述文字、图片URL处理记录表存的是流程轨迹哪个角色在什么时间把状态改成了什么。这两张表的配合让每个报修请求都有完整的时间线学生端可以实时看到“已派单”“维修工已接单”这些节点后端做接口时只需要返回时间线数组前端用时间线组件一渲染就搞定。报修单表的核心字段CREATE TABLE repair_order ( id BIGINT AUTO_INCREMENT PRIMARY KEY, order_no VARCHAR(32) NOT NULL COMMENT 工单号, student_id BIGINT NOT NULL, room_id BIGINT NOT NULL, repair_type VARCHAR(50) NOT NULL COMMENT 水电/家具/门窗/其他, description VARCHAR(500) NOT NULL, image_urls VARCHAR(1000) DEFAULT NULL, status TINYINT NOT NULL DEFAULT 0 COMMENT 0待派单 1已派单 2维修中 3待验收 4已完成 5已取消, assignee_name VARCHAR(50) DEFAULT NULL, create_time DATETIME DEFAULT CURRENT_TIMESTAMP, finish_time DATETIME DEFAULT NULL );状态流转这里我踩过一个坑。最初我把“待验收”和“已完成”合并成一个状态结果学生验收的售后评价就直接没了。后来拆开成两个状态加了验收时间和评分字段逻辑就顺了。这个细节在答辩时可以重点讲老师通常会追问“你的工单管理是闭合的吗”有验收和评分环节就能站得住脚。4. 学生端小程序的功能落地登录、报修与床位申请4.1 登录鉴权与学号绑定的实现细节小程序端第一个要解决的问题是身份认证。我的实现思路是三层配合第一层wx.login获取临时code后端通过HTTP请求微信的jscode2session接口换OpenID和SessionKey。第二层判断该OpenID是否已绑定学号如果没绑定小程序端弹出学号姓名绑定表单后端校验这个学号在教务库我这里做的是模拟校验通过查询学生表中的姓名是否匹配是否存在匹配则绑定成功。第三层以后每次请求后端都带着OpenID后端用一个自定义拦截器检查小程序的Session是否过期。说一个具体的坑wx.login的code有效期只有5分钟而且每次调用都会刷新。如果你在小程序端反复调用wx.login拿code换取OpenID后端的Session会被更新掉导致之前下发的登录凭证很快失效。正确的做法是小程序启动时调用一次wx.login拿到code换取登录token后续所有接口统一带token只有在token过期时才重新调用wx.login。登录接口的后端实现大概是这样的PostMapping(/api/auth/login) public Result login(RequestBody LoginRequest request) { String openId WxUtil.code2Session(request.getCode()).getOpenid(); User user userMapper.selectByOpenId(openId); if (user null) { return Result.error(1001, 未绑定学号).put(hasBind, false); } String token JwtUtil.generateToken(user.getId()); return Result.ok().put(token, token).put(hasBind, true); }这里用JWT而不是传统的Session是因为小程序端对无状态接口更友好后端重启后登录态也不会丢。学生绑定完学号后系统自动根据学号去匹配入住记录表匹配到就把宿舍信息楼栋、房间、床位带出来展示在首页。4.2 报修功能在小程序端的交互细节报修是小程序端使用频率最高的模块我在设计交互时花了不少心思。核心流程是学生进入报修页面选择报修类型我做了四个水电故障、家具损坏、门窗问题、其他填写位置自动带出宿舍号但允许手动修改用文字描述问题可选上传现场照片。提交后表单直接调用/api/repair/submit接口后端生成工单号、状态置为待派单。这里有一个值得分享的产品细节。初始版本我只做了“提交”按钮学生提交完就不知道后续进展导致大量重复报修——“我上周报的还没人来修我再报一次”。后来我在首页加了一个滚动公告栏专门展示“您的报修单工单号xxxx已被维修工接单预计今天18点前上门”同时在小程序端开放报修时间线页面学生点进去能看到每一步的操作人和时间。加了这两个东西之后重复报修率肉眼可见地下降了。报修提交页的代码逻辑里我特别注意了图片上传的异步问题。小程序的wx.uploadFile是单文件上传学生选完多张图片后前端得用Promise.all把图片全部传完再提交表单。如果急着提交图片链接还没返回就带着空数组走提交逻辑后端存了个空字符串报修单里没有图维修工找不到位置就很麻烦。我最后的处理方式是提交按钮默认置灰图片全部上传完成才点亮。4.3 新生床位申请并发问题从这里起步宿舍管理系统最刺激的场景是新生报到季的床位申请。几百个新生同一时间抢床位如果后端不做并发控制就会出现“一张床被两个人同时选中”的脏数据。我在做这个模块时深刻体会到数据库锁的重要性。我的实现方案是基于数据库的乐观锁与悲观锁结合。具体做法是在床位表设计一个version字段学生抢占床位的SQL语句是这样的UPDATE bed SET bed_status 1, version version 1 WHERE id #{bedId} AND bed_status 0 AND version #{oldVersion}如果update返回的影响行数是0说明床位已经被别人抢走了后端立即抛出“手慢了该床位已被选走”的提示。这个方法比先查询再更新的“检查-再操作”流程安全得多。我还在代码里加了synchronized关键词做单机锁兜底虽然集群环境下synchronized不够用但毕业设计体量的项目单机锁配合数据库乐观锁已经足够可靠。5. 管理端与数据可视化让宿舍数据“能说话”5.1 管理后台的权限模型设计管理后台我设计了三种角色宿管员、辅导员、系统管理员。权限区别在于数据范围和操作范围。宿管员能管自己负责的楼栋看到的是该楼栋的房间状态、入住名单、报修工单。辅导员则带院系属性能看到自己学院学生的分布和住宿情况。系统管理员拥有全部权限可以创建账号、分配楼栋、维护基础数据。权限控制的落地方式没有引入Shiro或Spring Security因为我担心这些框架的复杂度反而拖慢项目进度。我采用的是拦截器 注解的方式写一个RequireRole(ADMIN)注解加在需要权限的方法上拦截器里从token解析出用户角色判断是否放行。代码大概长这样Target(ElementType.METHOD) Retention(RetentionPolicy.RUNTIME) public interface RequireRole { String[] value(); }这个方案在毕业设计答辩时很好解释你只需要说“我用自定义注解和拦截器实现了轻量级的RBAC权限控制”即可比套一个大框架更有技术亮点。5.2 可视化大屏与 ECharts 的结合数据可视化部分是我个人最喜欢的模块也是答辩演示时最抓眼球的一块。我在管理后台做了一套宿舍数据大屏包含四个核心图表宿舍入住率趋势折线图、各楼栋空床位分布柱状图、报修工单类型饼图、近7日报修处理时效折线图。前端用ECharts后端提供统计数据接口返回JSON格式的汇总数据。比如各楼栋空床位分布柱状图后端只用一个SQLSELECT building_name, COUNT(*) AS total, SUM(CASE WHEN bed_status 0 THEN 1 ELSE 0 END) AS empty_beds FROM bed JOIN building ON bed.building_id building.id GROUP BY building_id, building_name前端拿到数据直接echarts.init(dom).setOption(...)一分钟就能出一个图。这里我想多说一句很多人以为数据可视化难在图表渲染其实难在数据清洗和聚合。比如“入住率趋势折线图”真实数据是每一天每个宿舍的入住状态需要按天做聚合去计算。我一开始直接查checkin_record表发现数据量一大就慢得不行后来改成用定时任务每天凌晨把当天的各楼栋入住率汇总到一张统计表里前端直接查汇总表图表秒开。大屏的布局方面我用的是Grid网格布局左边两列放楼栋概况和空床分布中间顶部放核心指标总床位、当前在住人数、空床数、待处理工单中间偏下放入住率趋势右侧放报修饼图和处理时效。整体配色用了深蓝色背景 亮色数据点投影到答辩的大屏幕上效果非常不错。5.3 报修工单的流转状态管理管理端的报修工单流转逻辑一开始我写得比较粗糙只有一个repair_order表的直接更新。后来发现当维修工、宿管员、学生三个角色同时操作同一张单子时状态会乱掉。比如宿管员先把单子派给维修工A维修工A接单后学生又取消了这时候维修工A手机上还挂着一个已经取消的单子活白干了。我的解決方案是状态流转全部走后端接口每次流转前检查前置状态。例如“接单”接口要求当前状态必须是“已派单”如果不是就返回“工单状态已变更请刷新”的错误提示。同时在处理记录表里写入每一步的操作轨迹前端时间线组件就能完整展示学生提交→宿管派单→维修工接单→维修完成→学生验收。每一步都有操作人、操作时间、备注。这个设计让报修流程变得可回溯也方便我做后面“维修时效”的统计直接用处理记录里的时间差来计算每个工单从提交到完成用了多少小时顺手就把超时工单筛出来催办。6. 开发与部署阶段踩过的坑6.1 定时释放床位自动化任务里的边界问题系统里有一个比较细节但很重要的功能新生预分配床位后如果超过某个时间点没有确认入住床位要自动释放回归到空闲池。我使用Spring内置的Scheduled注解写了定时任务每晚凌晨两点扫描“待确认”超过48小时的预分配记录批量更新床位状态。这个功能的坑在于定时任务跑的时候可能有学生恰好正在确认入住出现一种极端情况——学生在A时刻点确认入住而定时任务在A时刻前0.1秒已经扫过这张床看到“待确认超时”就把它释放了学生确认时发现床位不见了。我的解决方式是多加了一个前置检查释放床位前再次确认该记录的状态确实还是“待确认”并且把UPDATE语句带上状态条件影响行数为0就跳过。这样就算并发撞上数据库层面的状态校验也会挡住错误的释放操作。这是从电商库存扣减场景里学到的思路放到宿舍系统里同样管用。6.2 小程序真机调试时的图片上传问题开发小程序时模拟器里一切正常一上真机就会出现图片上传失败。排查了半天发现原因是我在本地开发时后端接口用的是http://localhost:8080小程序承载的是HTTPS协议真机上这种跨协议访问默认被拦掉。解决的方案是在微信开发者工具里勾选“不校验合法域名、web-view业务域名、TLS版本以及HTTPS证书”然后用内网穿透工具把本地后端映射成一个HTTPS地址供真机临时联调。部署上线时后端统一挂到有HTTPS证书的服务器上wx.uploadFile的url换成正式域名问题彻底解决。这个坑在答辩演示前一定要提前验证否则答辩现场用真机演示报修传图图片传不上去场面会非常尴尬。我的建议是无论时间多紧都要在答辩前一晚拿一台真机完整走一遍核心流程。6.3 部署时的内存与数据库连接池调优项目部署用的是学校的云服务器配置相对有限2核4G。Spring Boot默认的内存参数跑起来加上MySQL内存很容易飙到85%以上系统变得很卡。我做的优化有两个一个是修改JVM启动参数-Xms512m -Xmx1024m避免内存过度占用另一个是修改Tomcat的最大线程数和MySQL连接池大小。连接池的HikariCP配置我做了调整spring: datasource: hikari: maximum-pool-size: 20 minimum-idle: 5 connection-timeout: 30000这里有一个教训连接池开得越大不一定越快因为每个连接背后都是一条数据库线程4G内存的机器上开200个连接池MySQL直接被拖垮。我用20个连接处理并发实测高峰时期完全够用。6.4 关于“全套文案”和答辩准备的一点个人体会最后聊点题外话。很多做这类系统的人会把精力全部放在代码上等代码写完才发现毕业论文、开题报告、答辩PPT还一笔没动。我的经验是写论文和写代码最好同步推进每做完一个模块就把对应的功能描述、技术难点、测试结果整理成文档后面写论文时直接拼接润色就行。我在做这个宿舍管理系统的过程中最大的体会是一个看起来简单的管理系统真正落地时要考虑的点远比想象中多。从需求梳理的“宿管阿姨要什么”到数据库设计时的“床位状态怎么建模型”到并发场景下的“一张床不能分给两个人”再到答辩时的“我能把这个业务闭环讲清楚吗”每一步都是在逼自己像一个真正执行项目的开发者那样思考。这篇内容写到这里我把玉林师范学院宿舍管理系统从需求、设计、开发、可视化到部署的完整链路都过了一遍。如果你正在做类似的选题希望这些踩坑经验和设计思路能帮你少走一些弯路。后面有时间我再单独写一篇关于数据大屏设计细节和模拟数据生成脚本的内容。
阅读完成 · 觉得有帮助?
咨询建站