
宿舍管理系统这个题目在 GitHub 上和各种课设博客里已经不算新鲜了但打开搜索结果一看大量仓库还停留在 JSP Servlet 或者单体 JSP 的阶段真正把 SpringBoot Vue 前后端分离做完整、又能让新手直接跑起来的反而不多。我自己带过几届学生做这类项目也帮人排查过不少“代码一样但就是跑不起来”的疑难杂症所以看到这个标题还挺感慨它看起来是个标准课设但真要把它做到“能展示、能答辩、能扩展”里面的细节其实比想象中多得多。这篇就围绕这套基于 SpringBoot Vue MyBatis MySQL 的宿舍管理系统把我实际开发、部署、调试过程中踩过的坑和觉得有用的思路完整梳理一遍希望能给正在做类似系统的人一些参考。1. 这系统解决的到底是什么问题1.1 宿舍管理工作的真实痛点很多第一次接触这类项目的人会把宿舍管理系统简单理解成“登记住宿信息的 CRUD”。实际在高校后勤场景里宿舍管理比这个复杂。宿管阿姨要管的不只是“谁住哪个房间”还有新生入学分配、毕业生退宿清点、中途调宿变更、水电费统计、报修跟进、晚归记录、卫生评分以及频繁发生的换寝申请审批。这些工作如果用 Excel 表格做最大的问题不是“能不能记”而是“多头维护导致数据不一致”。保卫处有一份名单学院辅导员有一份名单宿管中心又有一份三份名单经常对不上。系统要解决的本质上是信息同步和流程规范化的问题。所以设计这套系统时我的第一个建议是不要一上来就写代码先把角色和流程搞清楚。宿舍管理系统里至少存在这么几类人系统管理员负责楼栋、房间、账号等基础数据、宿管员负责日常登记和审核、学生申请入住、报修、查看通知、辅导员查看本学院住宿情况。每一类人对系统的诉求不一样界面和操作路径也不一样。项目标题里虽然只写了“宿舍管理系统”但把这个角色模型拆清楚了后面的表结构和接口设计才会有依据。1.2 为什么这一套技术栈成了主流选择SpringBoot Vue MyBatis MySQL 这个组合在 2025 年来看已经是国内 Java 全栈开发的事实标准搭配尤其是在中小型管理系统领域。SpringBoot 省去了大量 XML 配置内置 Tomcat一个 main 方法就能起服务这对快速交付项目非常重要。Vue 的前端生态足够成熟Element UI 或 Element Plus 提供的表格、表单、弹窗组件几乎就是为管理后台量身定做的写页面效率非常高。MyBatis 的灵活之处在于 SQL 由自己掌控排查问题和调优都很直接没有 JPA 那种“黑盒”生成 SQL 的困扰。MySQL 则是开源数据库里最稳妥的选择部署简单资料也全。这四样东西组合起来还隐藏了一个对新手特别友好的特性生态里所有坑都被人踩过了。遇到环境变量配错、依赖冲突、版本不兼容这类问题搜索引擎基本能直接给出答案。这一点在项目交付阶段非常重要省下的排查时间可以用来打磨业务细节。1.3 千万不要掉进“技术炫技”的陷阱我见过不少同学把大量精力花在引入 Redis 做缓存、用 Elasticsearch 做搜索、给项目加一堆微服务组件上。不是说这些技术不好而是对一个日均访问量可能只有几十次的宿舍管理系统来说引入这些组件只会徒增部署复杂度和出问题概率。一个典型教训是有学生为了让简历“好看”给系统加了 Redis 缓存用户信息结果答辩演示时 Redis 没启动整个登录功能直接挂了。这种事故在项目演示现场是致命的。我的观点很明确宿舍管理系统的核心价值在业务闭环而不是技术堆叠。先把登录认证、权限控制、入住退宿流程、报修工单流转这些主线做扎实比什么都强。如果你确实想展示自己对缓存、消息队列的理解可以在答辩环节用“如果未来用户量增长我会如何演进”的口头描述带过而不是真的把系统搞复杂。2. 业务模型与模块边界梳理2.1 四种角色与权限边界我用一个实际项目作为例子来拆解。这个系统的用户表里通过role字段区分了四种角色ADMIN管理员、DORM_MANAGER宿管员、STUDENT学生、COUNSELOR辅导员。如果只做最简单的版本也可以只保留前三种但加上辅导员权限后整个系统的层次感会明显不一样。权限设计上需要思考的核心问题是谁可以改什么数据。管理员管理用户账号、楼栋、楼层、房间的增删改查还能查看全系统所有统计报表。宿管员负责学生的入住登记、退宿登记、调宿办理、卫生评分、报修处理。宿管员的日常操作量最大界面应该尽量“任务驱动”。学生申请入住、提交报修、查看个人住宿信息和通知公告。学生端操作少但入口要好找。辅导员只能查看本学院学生住宿情况数据要按学院的维度过滤。比如计算机学院的辅导员登录后只能看到计算机学院学生的入住数据。如果你是拿这套系统做毕业设计答辩时老师大概率会追问“你的权限是怎么控制的”。如果你能讲清楚“后端接口做了基于角色的拦截校验前端路由做了动态过滤而不是前端简单隐藏按钮”这就能成为一个不错的加分点因为它体现出你对安全设计有整体认识。2.2 核心流程拆解入住、退宿、调宿系统里最核心的业务流程是入住、退宿和调宿。这三个流程能否跑通直接决定了这个系统能不能用起来。先说入住。新生入学场景下管理员会先维护好宿舍楼和房间的基本信息然后由宿管员为学生办理入住。办理时系统要校验两件事一是目标房间是否还有空床位二是这个学生是不是已经处于“在住”状态。一个学生不能同时住在两个房间这个状态判断必须放在后端做不能只靠前端控制。如果这块不做校验就会出现同一张床位被分配给两个人的数据错误。退宿的逻辑其实比入住更繁琐。毕业季时一个宿舍四个人要同时退宿每张床位的被褥情况、物品损坏情况都要登记。退宿后系统需要释放床位资源同时把这个学生的住宿状态改成“已退宿”并且保留历史记录方便后续追溯。很多新手容易在这里犯一个错误直接删除住宿记录表里的数据。删除之后统计报表的数据就缺失了。正确做法是加一个status字段把退宿看成一次状态变更而不是物理删除。调宿可以理解为“先退宿再入住”的组合操作但在实际代码里最好做成一个独立方法放在一个事务里保证退旧房间和新房间的操作要么同时成功要么同时失败。这个事务逻辑在后面的代码部分会详细讲。2.3 辅助模块报修、卫生、公告核心流程之外还有几个模块能让系统更完整报修管理、卫生检查、通知公告。报修模块的流转链路是学生提交报修工单填写地点、问题描述、图片宿管员查看工单并派单或直接处理处理完成后更新工单状态学生能查看处理进度。这里的核心表字段至少包括报修人、报修位置、问题描述、状态、处理人、处理时间。一个容易被忽略的细节是状态流转新建、待处理、处理中、已完成、已评价要给出清晰的定义并用字典或常量管理不要用散落在代码里的魔法数字。卫生检查模块适合做成“宿管员按楼栋打分学生可查看分数”的结构。表设计上可以设计成dorm_health_check表字段包括检查宿舍、检查时间、评分项、分数、备注和检查人。评分不需要太复杂用总分制或者几个维度打分的组合都可以关键是历史数据要留得住方便做月度评比。公告模块看似简单但它是系统“活跃度”的来源。管理员或宿管员发布通知后学生端首页就能看到。实现上公告表字段包括标题、内容、发布人、发布时间、置顶状态。置顶功能虽小却很实用答辩时可以作为一个小亮点来介绍。3. 数据库表设计一张表一张表地讲3.1 用户表、学院表和宿舍楼表的关联设计数据库设计是面试和答辩里最常被问到的地方。宿舍管理系统的表不算难但表之间的关系要想清楚否则后患无穷。我通常会拆成几组表。第一组是基础资料类包括user用户、college学院、building宿舍楼、room房间。user表的核心字段id、username、password、real_name、role、college_id、student_no、phone、avatar。这里要注意密码不能明文存储至少要用 BCrypt 加密这是安全底线。college_id关联学院表这样辅导员按学院查数据时就有依据可以用。building表不用设计得太复杂字段可以是id、name、floors总楼层、sex_type男寝/女寝。room表的核心字段要有id、building_id、room_no、floor、bed_count总床位数、used_count已入住人数。used_count这个字段看起来有点冗余因为它实际上可以由入住记录实时统计出来但保留它有一个好处查询可用床位时列表页筛选空宿舍速度会快很多。维护方式是在办理入住和退宿时同步更新这个数值。这种“用空间换时间、允许适度冗余”的思路是实际项目里的常见做法面试官也比较认可。3.2 住宿记录表系统的核心业务表接下来是业务记录类最重要的一张表是dorm_record住宿记录表。字段建议这样设计id、student_id、room_id、bed_no床位号、check_in_time入住时间、check_out_time退宿时间、status在住/已退宿。这张表是判断一个学生当前住哪里的唯一依据。所有关于住宿的查询都应该基于这张表而不是基于房间表的used_count字段。一个实践中的细节查询“某个房间当前住了谁”时SQL 的过滤条件是room_id ? AND status ACTIVE查询“某个学生的住宿信息”时过滤条件是student_id ? AND status ACTIVE。只要保证办理入住时status设置为 ACTIVE、退宿时更新为 INACTIVE 并写入check_out_time数据的一致性就有保障。另外建议给student_id、room_id、status这三个字段建联合索引。数据量小的时候可能感觉不到区别但一旦记录到了几万条查询速度差别会很明显。这个点也可以写进你的数据库设计说明里属于加分项。3.3 报修、卫生、公告表然后是辅助业务表。repair_order报修表字段id、student_id报修人、room_id报修位置、description问题描述、image图片地址、status状态、handler_id处理人、handle_time处理时间、create_time。health_check表字段id、room_id、check_date、total_score、detail_score、remark、checker_id。announcement表字段id、title、content、publisher_id、is_top、create_time。这三张表设计思路一致记录谁、在什么时间、对什么对象、做了什么操作、结果怎样。把所有维度补齐报表就不愁没数据。3.4 用 SQL 初始化数据的注意事项数据库表建好之后初始化数据也很关键。建议写一个init.sql包含建库建表语句和必要的测试数据。测试数据要贴近真实场景比如建一栋“男生宿舍1号楼”和“女生宿舍1号楼”每栋楼六层每层 15 间宿舍每间宿舍 4 个床位。同时插入几个测试账号一个管理员、两个宿管员、几名不同学院的学生。为什么要做这一步因为前端页面渲染列表时需要真实数据看起来才像样你总不能在答辩时打开一个全是空表的系统。这里还要提醒一个新手常踩的坑MySQL 的字符集问题。建表时明确指定DEFAULT CHARSETutf8mb4否则插入中文数据可能变乱码。utf8mb4支持完整的 Unicode包括 emoji是 2025 年所有 MySQL 建库的默认选择。4. 后端实现SpringBoot MyBatis 的落地细节4.1 项目分层与包结构后端代码的组织方式直接决定这个项目后续好不好维护。我会按照常见的分层结构来组织也是目前企业项目里最标准的做法com.example.dorm ├── controller // 接收前端请求 ├── service // 业务逻辑层 ├── mapper // MyBatis 数据访问接口 ├── entity // 数据库实体类 ├── dto // 数据传输对象 ├── common // 通用返回结构、常量、异常处理 └── config // 配置类拦截器、跨域、WebMvccontroller 只做参数接收和结果包装不写业务代码。业务代码放在 service 层这样事务注解Transactional也打在 service 方法上。mapper 层只负责 SQL 和实体映射。这样的好处是出问题时能快速定位而且答辩时老师问你“业务逻辑写在哪一层”你能给出清晰回答。一个很实际的经验通用返回类ResultT必须设计好。它至少包括code、message、data三个字段成功时code200失败时code500或自定义错误码。前端 Axios 拦截器里对code做统一判断弹出错误提示。不要用裸的 List 或 Map 作为接口返回结果那样前端处理会非常痛苦也不规范。4.2 动态 SQL 与 XML 映射的实战写法再来说 MyBatis。日志里的“BindingException: Invalid bound statement” 是出现频率最高的报错之一原因绝大多数是 mapper 接口和 XML 文件没对应上。对应关系有两条硬性要求XML 的namespace必须等于接口的完整限定名XML 里每个语句的id必须等于接口的方法名。我自己的习惯是直接把 XML 文件和接口放在同一个包目录下这样 IDE 能自动关联排查时也方便。如果你用的是application.yml配置还需要确保mapper-locations路径写对比如classpath:mapper/*.xml并把 XML 放对资源目录。实际业务里查询条件经常是动态的比如列表页筛选“按楼栋筛选、按学院筛选、按状态筛选”筛选条件组合是不固定的。MyBatis 的where和if标签就能很好地处理select idselectRoomPage resultTypecom.example.dorm.entity.Room SELECT r.*, b.name AS building_name FROM room r LEFT JOIN building b ON r.building_id b.id where if testbuildingId ! null AND r.building_id #{buildingId} /if if teststatus ! null AND r.status #{status} /if /where ORDER BY r.id DESC /select这里我用LEFT JOIN的目的也很直观列表页要显示房间所属楼栋的名称如果不 join就需要在 service 层逐条二次查询也就是传说中的 N1 问题。数据量一多性能就很难看。一次 join 能搞定的情况不要循环查库。分页查询建议直接用 MyBatis-PageHelper 或 MyBatis-Plus 的分页插件。考虑到很多新手用的还是 MyBatis 原生的写法手写分页时用LIMIT #{offset}, #{pageSize}就可以了。注意计算 offset 的逻辑offset (pageNum - 1) * pageSize这个公式错一次就是半个小时的排查时间。4.3 登录认证与权限控制登录这块我从实际项目里总结出一个适合课设系统的方案JWT 登录态 Spring 拦截器校验。用户登录成功后后端生成一个包含用户 id、用户名、角色的 JWT token 返回给前端。前端存储在 localStorage或更稳妥的 HttpOnly Cookie 方案里之后每次请求在请求头带上Authorization: Bearer token。后端用一个拦截器统一校验 token。校验通过后把用户信息放到ThreadLocal或请求 attribute 中后续的 controller 方法就能从上下文中获取当前登录用户。权限控制上可以做一个简单的RequireRole(ADMIN)注解配合 Spring AOP 拦截指定角色或者更简单一点在拦截器里判断请求路径前缀比如/admin/**必须 ADMIN 角色才能访问。这里我特别想提醒一个坑很多人在前端把“按钮显示/隐藏”当成了权限控制但前端隐藏不等于安全。真正的安全检查必须放在后端。举例来说一个学生如果通过 DevTools 手动调用“删除宿舍楼”的接口后端如果不校验角色接口是照样能跑通的。所以后端接口必须对角色做显式校验这个点是我在课程设计和项目答辩环节反复强调的。4.4 事务处理与数据一致性再回到调宿场景。调宿时要做两步操作释放旧床位旧记录状态改 INACTIVE和分配新床位插入新记录。如果第一步成功、第二步失败就会出现学生无家可住的数据问题。Java 里最简单的处理方式是在 service 方法上加Transactional注解让这两个数据库操作在同一个数据库事务里执行要么都提交要么都回滚。但注解事务有个生效前提方法不能是 private且必须通过 Spring 代理调用。实际开发中我经常碰到有人把Transactional写在 controller 方法上结果数据出了问题不知道回滚没。正确用法是加在 service 类的 public 方法上。这个方法里如果捕获了异常记得要重新抛出 RuntimeException否则 Spring 默认不会对 checked exception 回滚这也是一个很容易被忽略的隐蔽问题。5. 前端实现Vue 管理后台的通用套路5.1 环境准备与工程搭建前端用的是 Vue。2025 年这个时间节点新项目我建议直接上 Vue 3 Vite Element Plus如果对 Vue 2 特别熟悉用 Vue 2 Vue CLI Element UI 也没有问题维护老项目够用。以 Vue 3 为例创建项目的命令是npm create vitelatest dorm-frontend -- --template vue cd dorm-frontend npm install npm install element-plus axios vue-router piniaElement Plus 对管理后台的开发效率提升非常明显。表格用el-table表单用el-form弹窗用el-dialog再加上el-menu做侧边栏几小时就能搭出标准的后台界面。很多新手会在“自定义样式”上消耗大量时间但这个系统最重要的是功能完整和页面可用不需要在花里胡哨的样式上钻牛角尖。5.2 路由、状态管理与请求封装Vue 的路由要区分两种公共路由登录页、404和需要登录的路由主布局内的所有页面。路由守卫里做登录判断访问需要登录的页面时没有 token 就跳转登录页。这个思路很简单但不能做权限精确控制。更进阶的做法是动态路由登录时拿到用户角色前端根据角色映射表动态添加路由。我建议至少要实现到“菜单根据角色动态展示”这一层答辩时很有说服力。状态管理用 PiniaVue 3 的推荐方案或 VuexVue 2。需要存的状态只有一个当前登录用户信息昵称、头像、角色。这块存储里不要放密码也不要放 token 之外的敏感信息。Axios 封装上统一做三件事请求拦截器加 Authorization 请求头响应拦截器处理code ! 200的错误提示网络异常时做统一弹窗。三个拦截器搞定全部请求后续页面代码只需要封装具体的接口方法比如登录接口、入住接口、报修接口避免每个页面都重复写 axios 配置。5.3 页面构建模式表格 弹窗 表单管理后台所有页面的开发模式本质上可以统一归纳为“表格展示 弹窗编辑”。列表页用el-table展示数据操作列放编辑、删除按钮新增和编辑共用同一个el-dialog弹窗里的el-form表单。这种模式抽成通用组件后整个系统的页面开发速度会快很多。几个细节经验表格里的时间字段建议后端返回LocalDateTime前端做格式化显示“2025-06-18 14:30”不要直接显示一长串 ISO 时间戳。状态字段比如在住/已退宿建议用el-tag显示不同颜色绿色代表正常、灰色代表已退宿界面信息一目了然。搜索区放楼栋下拉框、状态下拉框、关键字输入框点击“查询”按钮后重新请求列表接口。我在写前端接口时会把所有接口地址集中放在一个api目录里按模块拆分比如api/user.js、api/room.js、api/repair.js。统一管理的好处是后端接口路径变更时前端只要改一处不会出现全局搜索替换的尴尬。6. 打包部署前后端怎么放到一起6.1 前端构建与产物处理很多新手搞不明白“前端项目怎么跑起来给别人展示”。开发阶段前端用 Vite 开发服务器默认 5173 端口后端用 Spring Boot 内嵌 Tomcat默认 8080 端口前端通过 Vite 的代理配置解决跨域也就是server.proxy里把/api开头的请求转发到http://localhost:8080。这是开发环境的标准做法。等到需要演示或部署时前端要执行npm run build生成dist目录。dist里面是纯静态文件index.html、assets目录等。这一步很多人会困惑“dist 怎么用” 答案很简单要么把dist里的内容交给 Nginx 之类的 Web 服务器托管要么把dist里的文件直接放到 Spring Boot 的src/main/resources/static目录下然后重新打后端 jar 包。这样只启动后端一个进程打开http://localhost:8080就能看到前端页面非常方便。6.2 单独部署与合并部署的选择这两种部署方式各有适用场景。前后端完全分离部署前端放 NginxNginx 配置反向代理/api到后端服务。好处是前端静态资源和后端服务彻底分开升级互不影响。缺点是部署环境需要多装一个 Nginx对新手来说配置门槛略高。合并部署前端打进 Spring Boot简单省事一个 jar 包搞定。适合课程设计答辩、小型项目交付。缺点是一旦前端改了页面需要重新执行 build 并把产物拷贝到 static 目录再重新打包整个 jar。如果改得很频繁会有点繁琐。我自己的建议是课程设计和毕业答辩场景优先选合并部署。因为演示现场环境不可控一个单 jar 包最不容易出问题。等你进入企业实习或做真实线上项目再切换成 Nginx 前后端分离的模式也不迟。这里补充一个选择合并部署时经常会遇到的坑前端构建时axios请求的 baseURL 不能写死成http://localhost:8080否则上线后请求还是会打到本机。更稳的写法是使用相对路径/api这样无论部署在哪个域名或端口下请求都会自动走当前 host。后端 controller 统一加/api前缀或者通过server.servlet.context-path/api配置全局前缀。这种设计让前端在开发环境和生产环境之间切换时不用改一行代码。6.3 Spring Boot 部署细节备忘打包用 Mavenmvn clean package生成 jar。启动时注意几个关键点第一检查 MySQL 是否已经启动、账号密码是否和application.yml里配置的一致。第二检查数据库是否导入了初始 SQL。第三运行 jar 后看日志找到“Started Application in x.xxx seconds”才代表启动成功。第四防火墙或云服务器的安全组要放行对应端口否则别人访问不到你的 8080。配置上建议把数据库连接信息放在application.yml里并用${MYSQL_HOST:localhost}这类占位符支持环境变量覆盖。这样做的好处是未来从本地环境切到服务器时不用改代码只要设置环境变量就行。7. 常见问题排查实录7.1 跨域、端口与连接类问题这是联调阶段出现频率最高的一类问题。现象前端页面能打开但所有 API 请求都报错控制台显示 “Access to XMLHttpRequest ... has been blocked by CORS policy”。原因一般是前端开发服务器5173和后端8080端口不同导致浏览器跨域拦截。解决方案开发环境用 Vite 代理转发不要用axios.defaults.baseURL http://localhost:8080这种硬编码方案后端如果确实需要开启跨域写一个 WebMvcConfigurer 配置类允许指定来源的请求而不是用CrossOrigin加在每个方法上加重代码负担。现象前端请求能发出但后端一直报 404。先确认后端有没有把静态资源目录映射好或者接口路径和前端请求路径是否完全一致尤其是斜杠后缀/api/room和/api/room/在 Spring Boot 里可能表现不一样。其次看后端控制台有没有打印No mapping for POST /api/xxx有的话说明路径没对上去 controller 检查RequestMapping和PostMapping的配置。7.2 MyBatis 绑定、映射与慢 SQL 排查“Invalid bound statement (not found)”这个错十个人里九个都遇到过。排查步骤按顺序来第一步看接口所在包和 XML namespace 是否一致第二步看接口方法名和 XML 里 SQL 的 id 是否一致第三步看 application.yml 里mapper-locations路径是否正确是否覆盖到了 XML 所在目录第四步检查 target 目录下有没有 XML 文件如果 IDE 没把 XML 编译到 classpath需要手动指定资源目录或重新构建项目。多数情况卡在第三步和第四步。再有一个常见问题是“查询女生宿舍的列表结果把男生宿舍也查出来了”显示逻辑上往往是把楼层数和楼号搞混了。排查方式很直接先跑一遍 SQL 看结果对不对再在 Mapper 方法上打断点看传参对不对最后看前端搜索组件的绑定值有没有错。MyBatis 的缓存机制也值得了解。一级缓存默认开启作用域是一个 SqlSession二级缓存默认不开启需要配置。对宿舍管理系统这种小数据量场景默认配置完全够用如果自己手动开启了二级缓存反而要小心“脏读”问题。本来这个系统就不需要多级缓存来提升性能真要缓存优先考虑加个简单 Spring Cache 即可。7.3 版本兼容类问题2025 年这个时间点常见的版本坑主要有这几个MySQL 8.0 默认认证插件是caching_sha2_password如果 JDBC 驱动版本太老连接时会报Public Key Retrieval is not allowed或者认证失败。解决方案升级 MySQL Connector/J 到 8.0.x 版本或者连接 URL 上加allowPublicKeyRetrievaltrueuseSSLfalse。Spring Boot 3.x 要求 JDK 17 或更高如果你还在用 JDK 8就要用 Spring Boot 2.7.x。很多课程设计项目还在用 JDK 8上传代码的人用 JDK 17环境差异会导致启动直接失败。项目文档里一定要写清 JDK、Spring Boot、MySQL 的版本匹配关系。Vue 3 的项目安装依赖时如果 Node 版本太老npm install 会报错。建议 Node 用 18 及以上 LTS 版本npm 尽量保持较新版本。有些人电脑上同时装了多个 Node 版本记得检查node -v确认实际生效的是哪一个。排查版本问题有一个总原则先看报错堆栈的第一行再对照 Spring Boot 官方文档里“版本对应关系”表格。大多数情况下版本不匹配的报错信息写得非常明显比如 class version 错误、NoSuchMethodError很多人卡住只是因为没耐心读堆栈前三行。8. 一些真正值得改进的扩展方向如果基础功能都跑通了还有余力可以考虑加一些低成本但高收益的扩展点。这些内容写进论文或答辩 PPT 里能显著提升项目的完整度。第一个扩展方向是数据可视化。宿舍管理系统天然有很多可统计的数据各楼栋入住率、各学院住宿人数、报修工单完成率、卫生评分趋势。用 ECharts 在前端做一个“数据看板”页面展示几张统计图项目观感立刻提升一个档次。后端只需要多写几个聚合查询接口技术难度不高但演示效果很好。第二个方向是导入导出。把住宿名单、报修工单导出成 Excel是很多宿舍管理工作的实际需求。后端用 Apache POI 或 EasyExcel 生成 Excel 文件前端用一个导出按钮触发下载。代码量不大但场景真实、实用性强面试时提到这个功能也比较加分。第三个方向是消息通知。比如报修工单状态变化时通知学生“你的报修已被处理”宿管员发布新公告时学生端首页弹窗提示。最简单的实现就是在前端轮询接口或者用 WebSocket 做推送。如果不想增加复杂度轮询一小时一次也完全可接受系统小轮询完全顶得住。第四个方向是操作日志。用 AOP 切面记录下关键操作谁在什么时间办理了入住、谁删除了楼栋信息。日志表不需要很复杂user_id、action、target、create_time就够。这个功能能让你在答辩时回答“你怎么保证数据安全和可追溯”是低成本的加分设计。最后分享一点实操体会我个人做这类项目最深刻的体会是与其羡慕别人仓库里功能多花哨不如把自己手里的主流程做得足够扎实。宿舍管理系统看着是普通课设但它把角色权限、流程状态、前后端交互、数据库事务这些后端开发里的基础功全部串了起来。我自己在带新人时经常说如果一个初学者能把这种项目从零到一完整做出来并且能讲清楚每一个设计理由那他现在出去找一份 Java 实习工作技术上是有底气的。最后再分享一个小技巧做完项目后花半小时写一个 README 放在仓库里。里面写清楚项目简介、所用技术版本、数据库初始化步骤、启动步骤和几个测试账号。这个 README 不只是给别人看的也是给未来的自己看的。往往过半个月再看自己的代码你就会感谢当时写了文档的自己。宿舍管理系统只是一个缩影这个套路适用于所有类似的管理系统项目。