news 2026/11/4 2:45:42

基于SpringBoot+Vue的Java宿舍报修管理系统实战:从部署到二次开发

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
基于SpringBoot+Vue的Java宿舍报修管理系统实战:从部署到二次开发

简介:这份资源面向计算机专业学生与Java Web初学者,提供一套基于Java的宿舍报修管理系统完整毕业设计资料,包含论文与配套源码,可用于课程设计、毕业设计参考或校园后勤维修管理场景的技术学习。压缩包共1个docx文件,约4.78MB,内容涵盖系统摘要、绪论、相关理论与技术、系统分析等章节,围绕Java语言、SpringBoot框架、Vue前端与MySQL数据库展开,并涉及Navicat、IDEA与Tomcat等工具的使用说明。系统功能覆盖用户管理、维修员管理、宿舍类型与信息管理、配件分类与设备管理、维修类型管理、宿舍分配、报修信息与接单管理、配件申请及维修进度管理等模块,论文对可行性分析、需求与设计思路有较完整论述。目前已有433人学习,适合需要参考完整论文结构、理解前后端分离实现方式并对照功能模块梳理开发思路的读者。

1. 从一张手写报修单说起:这套 Java 宿舍报修系统到底解决什么问题

宿舍楼管阿姨桌上那本翻烂的报修登记本,大概是很多高校后勤最真实的写照:学生跑来口头说一句“302 厕所漏水”,阿姨拿笔一记,维修师傅什么时候看到全凭缘分,修没修完也没人回访。这套基于 Java 的宿舍报修管理系统,干的就是把这本登记本搬进浏览器的事。后端 Java + SpringBoot 提供接口,前端 Vue 做交互,MySQL 存数据,Navicat 管库,IDEA 开发、Tomcat 部署,一套典型的教学级全栈组合。它把管理员、用户、维修员三类角色串成一条完整链路:学生在线下单报修,维修员接单并申请配件,管理员在后台盯着宿舍信息、配件库存和维修进度。适合拿来做课程设计、毕业设计,也适合想练手 SpringBoot + Vue 前后端分离的开发者照着跑一遍。

2. 技术栈与目录结构:一套标准的前后端分离骨架

2.1 为什么是 SpringBoot + Vue 这套组合

这个项目的技术选型没有太多花活,但每一步都踩在教学项目的舒适区里。后端用 Java 语言配 SpringBoot 框架,最大的好处是省掉了传统 SSM 那套 XML 配置的折磨——SpringBoot 自带容器扫描和自动装配,一个启动类加几个注解就能把 Web 服务拉起来,对于要在一两个月内交出完整系统的场景来说,这是实打实的效率。前端选 Vue,是因为它上手曲线平缓,模板语法接近 HTML,配合 Element UI 这类组件库,表格、分页、弹窗这些后台管理页面的高频元素基本是复制粘贴改字段名。数据库 MySQL 负责持久化,Navicat 做可视化管理,建表、改字段、导数据都比命令行顺手。服务器用 Tomcat 承载,IDEA 作为集成开发环境把编码、调试、打包串起来。

需要说清楚的是,这套组合里前后端是分离的:Vue 打包后的静态资源可以单独部署,通过 HTTP 请求调用 SpringBoot 暴露的接口,两边靠 JSON 通信。这种结构的好处是前端改页面不用重启后端,后端改逻辑也不影响前端调试,坏处是跨域问题得自己处理——常见做法是在 SpringBoot 里加一个全局跨域配置类,或者在 Vue 开发服务器里配 proxy 代理。我一般倾向后者,开发阶段省事,上线时再用 Nginx 统一转发。

2.2 目录结构长什么样

拿到源码后先别急着点运行,把目录翻一遍心里才有底。这类项目通常是两个独立工程放在一个压缩包里,一个后端一个前端,结构大致如下:

dorm-repair/ ├── backend/ # SpringBoot 后端工程 │ ├── src/main/java/ │ │ └── com/example/repair/ │ │ ├── RepairApplication.java # 启动类 │ │ ├── controller/ # 接口层,按业务分文件 │ │ │ ├── UserController.java │ │ │ ├── RepairController.java │ │ │ └── ... │ │ ├── service/ # 业务逻辑层 │ │ ├── mapper/ # 数据访问层(MyBatis) │ │ ├── entity/ # 实体类,与表字段对应 │ │ └── config/ # 跨域、拦截器等配置 │ ├── src/main/resources/ │ │ ├── application.yml # 数据库连接等配置 │ │ └── mapper/ # MyBatis 的 XML 映射文件 │ └── pom.xml # Maven 依赖 ├── frontend/ # Vue 前端工程 │ ├── src/ │ │ ├── views/ # 页面组件,按模块分目录 │ │ ├── api/ # 接口请求封装 │ │ ├── router/ # 路由配置 │ │ └── main.js # 入口 │ ├── package.json │ └── vue.config.js # 开发代理配置 └── sql/ └── dorm_repair.sql # 建库建表脚本

后端的分层是标准的 Controller → Service → Mapper 三层,实体类字段和数据库表一一对应,MyBatis 的 XML 里写 SQL。前端 views 目录下每个业务模块一个文件夹,里面放列表页和编辑弹窗。sql 目录里的脚本是跑通项目的关键,先导入它再启动后端,否则接口一调就报“表不存在”。

2.3 数据库表设计的关键几张

从论文的物理设计部分能看出,这套系统的表是按业务实体拆的,核心几张值得先摸清:

表名作用关键字段
users管理员账号username、password、role
yonghu用户(学生)信息用户账号、姓名、联系方式
sushexinxi宿舍信息宿舍名称、类型、楼栋、房间号、可住/已住人数
sushefenpei宿舍分配用户账号、床位号、分配日期
token登录凭证userid、token、过期时间

token 表的存在说明登录不是简单的 session 方案,而是登录成功后发一个 token,后续请求带着它做身份校验。这种设计在前后端分离项目里很常见,因为前端拿 token 存本地,刷新页面不掉登录态。宿舍信息表里“可住人数”和“已住人数”分开存,是为了分配床位时能实时算剩余容量,避免超分。

3. 跑起来:从导库到登录的完整步骤

3.1 环境准备与数据库导入

动手之前把环境对齐,版本不匹配是新手翻车的第一大来源。需要准备的东西:JDK 8 或以上(SpringBoot 2.x 系列对 JDK 8 友好)、Maven 3.6+、MySQL 5.7 或 8.0、Node.js 14+ 配 npm、IDEA 和 Navicat。装好后先确认命令行里java -version、mvn -v、node -v都能正常输出。

数据库这一步别偷懒,用 Navicat 连上本地 MySQL,新建一个库,字符集选 utf8mb4,然后运行 sql 目录下的脚本:

-- 新建数据库,字符集用 utf8mb4 避免中文乱码 CREATE DATABASE dorm_repair DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; -- 导入脚本后确认核心表是否建好 USE dorm_repair; SHOW TABLES; -- 预期能看到 users、yonghu、sushexinxi、sushefenpei、token 等表

脚本里通常还会插入一条管理员初始账号,导入完去 users 表里看一眼,记下用户名和密码,后面登录要用。如果 SHOW TABLES 出来的表名是乱码或者缺表,多半是脚本编码不对,用 Navicat 的“运行 SQL 文件”功能重新导一次,别用复制粘贴。

3.2 后端配置与启动

后端工程用 IDEA 打开 backend 目录,等 Maven 把依赖拉完。然后改application.yml里的数据库连接,这是必须动的地方:

spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/dorm_repair?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai username: root password: 你的数据库密码

serverTimezone这个参数别省,MySQL 8.0 驱动不配时区经常报连接失败。url 里的库名要和上一步建的一致。改完找到启动类,右键 Run,控制台出现 Tomcat started on port 8080 之类的日志就说明起来了。这时候浏览器访问http://localhost:8080可能是个 404 或者 Whitelabel 页面,正常,因为后端只提供接口,没有首页。

验证接口通不通,可以随便挑一个查询接口在浏览器里敲,比如用户列表接口,能返回 JSON 就说明数据库链路是通的。如果报 500,先看控制台异常栈,十有八九是表名或字段名对不上,回去核对实体类和表结构。

3.3 前端启动与联调

前端工程进 frontend 目录,先装依赖再跑:

# 安装依赖,国内网络慢可以换镜像源 npm install # 启动开发服务器,默认 8081 或 8082 端口 npm run serve

启动前看一眼vue.config.js里的代理配置,确认它把/api之类的请求前缀转发到了http://localhost:8080。如果没配代理,前端直接请求后端就会撞上跨域,浏览器控制台一片红。配好代理后,浏览器打开前端地址,用之前记下的管理员账号登录,能进后台首页、左侧菜单能点开各个管理模块,这条链路就算跑通了。

提示:前端端口和后端端口不能冲突,如果 8080 被后端占了,前端开发服务器会自动换端口,以控制台实际输出为准。

3.4 三类角色的功能走查

跑通登录后别急着改代码,先把三类角色的主流程各走一遍,心里才有业务全貌。管理员登录后能看到用户管理、维修员管理、宿舍类型、宿舍信息、配件分类、配件设备、维修类型、宿舍分配、报修信息、报修接单、配件申请、维修进度这一整排菜单,每个菜单基本是“列表 + 新增/编辑/删除”的套路。用户(学生)登录后能查宿舍信息、提交报修单、看自己的报修记录和维修进度。维修员登录后能看派给自己的单子、接单、申请配件、更新维修进度。走查时重点看报修单从提交到接单再到完成的状态流转,这是整个系统的主线,其他模块都是围着它转的。

4. 核心模块拆解:一条报修单的完整生命周期

4.1 登录与 token 校验链路

登录是整个系统的入口,也是理解权限设计的钥匙。前端提交账号密码到后端,后端查 users 表比对,成功后生成 token 写进 token 表并返回给前端。核心逻辑大致是这样:

// 登录接口:校验账号密码,生成 token 并落库 @PostMapping("/login") public Result login(@RequestBody LoginForm form) { // 按用户名查管理员记录 Users user = usersService.findByUsername(form.getUsername()); if (user == null || !user.getPassword().equals(form.getPassword())) { return Result.error("账号或密码错误"); } // 生成唯一 token,设置过期时间 String token = UUID.randomUUID().toString().replace("-", ""); TokenRecord record = new TokenRecord(); record.setUserid(user.getId()); record.setUsername(user.getUsername()); record.setRole(user.getRole()); record.setToken(token); record.setExpiratedtime(new Date(System.currentTimeMillis() + 2 * 60 * 60 * 1000)); tokenService.save(record); return Result.ok(token); }

这段代码里几个点值得注意:密码是明文比对,教学项目常见做法,真上生产得加 BCrypt 之类的哈希;token 用 UUID 生成,去掉了横杠方便前端存;过期时间设了两小时,过期后前端请求会被拦截器挡下来,跳回登录页。拦截器的逻辑一般是在config目录下,对除登录注册外的接口校验请求头里的 token 是否存在且未过期。改这块的时候,如果想让登录态更持久,把过期时间调大就行,但别忘了 token 表会越积越多,得配个定时清理或者登录时先删旧记录。

4.2 报修信息管理与接单流转

报修单是系统的核心实体,用户提交时写入报修信息表,字段包括报修人、宿舍、故障描述、报修类型、状态等。维修员在接单管理里看到待接单列表,点接单后状态变更,同时把维修员信息和接单时间写进去。下面是一个典型的接单接口:

// 维修员接单:更新报修单状态并绑定维修员 @PostMapping("/accept") public Result accept(@RequestParam Long repairId, @RequestParam Long workerId) { RepairInfo repair = repairService.getById(repairId); // 只有待接单状态才能接,防止重复接单 if (repair == null || !"待接单".equals(repair.getStatus())) { return Result.error("该报修单已被接单或不存在"); } repair.setStatus("维修中"); repair.setWorkerId(workerId); repair.setAcceptTime(new Date()); repairService.updateById(repair); return Result.ok(); }

这里的并发问题在教学项目里通常被忽略,但值得知道:两个维修员同时点接单,如果不在数据库层加乐观锁或者用update ... where status = '待接单'的条件更新,可能出现重复接单。我一般会把更新语句改成带状态条件的写法,影响行数为 0 就说明被别人抢先了。状态字段用中文字符串存,好处是前端直接展示不用映射,坏处是后期加状态得改代码,规范做法是用枚举或者数字字典表。

4.3 配件申请与库存联动

维修员修东西要用配件,所以有配件申请模块。维修员提交申请,管理员审批,审批通过后从配件设备表里扣减库存。这条链路的关键是库存扣减不能扣成负数:

// 审批配件申请:通过则扣减库存,库存不足直接拒绝 @PostMapping("/approve") public Result approve(@RequestParam Long applyId, @RequestParam boolean pass) { PartsApply apply = partsApplyService.getById(applyId); if (apply == null || !"待审批".equals(apply.getStatus())) { return Result.error("申请单状态异常"); } if (pass) { // 条件更新:库存足够才扣减,避免超卖 int rows = partsService.reduceStock(apply.getPartsId(), apply.getCount()); if (rows == 0) { return Result.error("配件库存不足,无法通过"); } apply.setStatus("已通过"); } else { apply.setStatus("已驳回"); } partsApplyService.updateById(apply); return Result.ok(); }

reduceStock对应的 SQL 是update parts set stock = stock - #{count} where id = #{id} and stock >= #{count},靠 where 条件保证不会扣成负数,返回影响行数判断成败。这种写法比先查再改安全,是库存类业务的常规操作。配件分类和配件设备是两级结构,分类管大类,设备管具体型号和库存,建表时用分类 id 关联。

4.4 宿舍分配与容量控制

宿舍分配模块把用户和宿舍床位绑起来,分配时要校验宿舍剩余容量。宿舍信息表里存了可住人数和已住人数,分配成功后已住人数加一,退宿则减一。核心校验逻辑:

// 分配宿舍:校验剩余床位后再写入分配记录 @PostMapping("/assign") public Result assign(@RequestBody AssignForm form) { DormInfo dorm = dormService.getById(form.getDormId()); int remain = Integer.parseInt(dorm.getKezhurenshu()) - Integer.parseInt(dorm.getYizhurenshu()); if (remain <= 0) { return Result.error("该宿舍已满员"); } // 写入分配记录 DormAssign assign = new DormAssign(); assign.setYonghuzhanghao(form.getUserAccount()); assign.setChuangweihao(form.getBedNo()); assign.setFenpeiriqi(new Date()); dormAssignService.save(assign); // 已住人数加一 dormService.increaseOccupied(dorm.getId()); return Result.ok(); }

注意可住人数和已住人数在表里是 varchar 类型,代码里得转成整数再算,这是建表时类型选得不严谨留下的坑,二次开发时建议改成 int。床位号是否重复、同一用户是否已分配,这些校验也得补上,否则数据会乱。

5. 避坑与排查:跑这套系统最容易栽的几个地方

5.1 中文乱码从建库就开始了

现象:页面上的宿舍名称、故障描述显示成问号或者方块。原因:建库时字符集用了 latin1 或者默认值,或者 JDBC url 里没带characterEncoding=utf8。解决:建库语句显式指定DEFAULT CHARACTER SET utf8mb4,连接串加上useUnicode=true&characterEncoding=utf8,Navicat 里看表设计确认字段字符集也是 utf8mb4。已经建错的库,改字符集比重建还麻烦,直接删库重导脚本更快。

5.2 端口冲突导致前端连不上后端

现象:前端登录一直转圈,控制台报ERR_CONNECTION_REFUSED或者 404。原因:后端没起来、端口不是 8080,或者vue.config.js里的代理目标写错了。解决:先看后端控制台确认实际端口,再核对代理配置里的 target 地址,两边端口必须一致。如果 8080 被别的程序占了,改后端application.yml里的server.port,同步改前端代理。

5.3 表字段和实体类对不上

现象:接口报 500,异常栈里出现Unknown column或者字段值为 null。原因:实体类属性名和数据库字段名不一致,MyBatis 没配驼峰映射。解决:在application.yml里加mybatis.configuration.map-underscore-to-camel-case: true,让下划线字段自动映射到驼峰属性;或者检查 XML 里的 resultMap 是否写全。改表结构后记得同步改实体类,两边脱节是这类项目最常见的低级错误。

5.4 登录后刷新页面掉登录态

现象:登录成功进首页,一按 F5 就跳回登录页。原因:token 只存在了 Vuex 内存里,没持久化到 localStorage,刷新就丢。解决:登录成功后把 token 同时写进 localStorage,路由守卫里优先从 localStorage 读,请求拦截器统一带上。退出登录时清掉。这个改动不大,但体验差别明显。

5.5 配件库存扣成负数

现象:配件申请审批通过后,库存显示为负。原因:扣减逻辑是先查库存再更新,中间没有条件约束,并发或者重复提交时穿透了。解决:把更新语句改成where stock >= #{count}的条件更新,用影响行数判断是否成功,失败就回滚申请状态。同时前端提交按钮加防重复点击。

6. 二次开发:从能跑到能用的改造思路

这套系统跑通之后,真正花时间的是把它往“能用”的方向推。我一般按优先级排三件事。第一件是把权限做细,现在 token 表里存了 role,但接口层未必每个都校验角色,容易出现学生调管理员接口的情况。改造方式是在拦截器里解析 token 拿到 role,配合自定义注解在 Controller 方法上标注允许的角色,拦截器统一比对,比在每个方法里写 if 判断干净得多。第二件是把状态字段规范化,报修单的“待接单/维修中/已完成”这类中文字符串散落在代码各处,改成枚举类集中管理,前端通过字典接口拿状态列表渲染下拉框,以后加“已取消”状态只改一处。

第三件是补统计报表,管理员端现在只有列表,没有数据看板。加一个统计接口,按维修类型分组统计报修量、按月份统计完成率,SQL 用group by加聚合函数就能出,前端用 ECharts 画两个图,答辩或者演示时观感提升明显。下面是一个按类型统计的示例:

-- 按维修类型统计报修单数量与完成数 SELECT weixiuleixing AS type, COUNT(*) AS total, SUM(CASE WHEN status = '已完成' THEN 1 ELSE 0 END) AS finished FROM baoxiuxinxi GROUP BY weixiuleixing ORDER BY total DESC;

验证改造是否生效,别只看页面,用 Postman 或者浏览器直接打接口,确认返回结构和前端渲染一致;改数据库字段后,先跑一遍全流程走查,从登录到报修到接单到完成,任何一环断了都能立刻定位。还有个小技巧:把application.yml里的 SQL 日志打开(mybatis.configuration.log-impl: org.apache.ibatis.logging.stdout.StdOutImpl),控制台能直接看到执行的 SQL 和参数,排查字段问题时比猜快得多。

血泪经验是,这类教学项目最容易犯的错是拿到就改业务代码,结果改崩了不知道哪一步出的问题。我现在的习惯是先把原始版本完整跑通、走查一遍、打个压缩包备份,再动第一行代码。每改一个模块,先确认原功能没坏,再往下走。希望帮到你。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/11/4 2:45:40

Aras PLM后台配置顺序与权限建模避坑指南

简介&#xff1a;《Aras 学习文档》是一份面向 Aras PLM 初学者、系统管理员及实施顾问的 Word 版系统管理使用手册&#xff0c;主要解决用户与权限配置、基础数据建模以及日常系统管理中的入门问题。压缩包内共 1 个 docx 文件&#xff0c;约 11.06MB&#xff0c;以章节目录组…

作者头像 李华
网站建设 2026/11/4 2:45:09

高校工资系统需求分析模板:模块化功能+权限矩阵+环境约束

简介&#xff1a;本资源是一份面向系统工程与软件工程初学者及项目实践者的《需求分析模板》文档&#xff0c;聚焦高校信息化管理场景&#xff0c;特别适用于工资管理系统等业务型软件的需求梳理与文档编写。文档以西北农林科技大学工资管理系统为典型案例&#xff0c;完整覆盖…

作者头像 李华
网站建设 2026/11/4 2:44:34

Android后台拍照实战:CameraX生命周期解耦与前台服务实现

简介&#xff1a;这份资源面向需要在应用退居后台时仍能调用相机完成拍摄的 Android 开发者&#xff0c;聚焦实时监控、图像记录等场景下的实现思路。内容围绕 Service 后台运行、CAMERA 运行时权限申请、Camera 与 Camera2 两套 API 的取舍、Bitmap 压缩与图片处理、WakeLock …

作者头像 李华
网站建设 2026/11/4 2:44:32

CATIA中文三维文字制作:CAD空心字轮廓导入与凸台拉伸全流程

简介&#xff1a;这份资源是面向CATIA初学者与产品设计人员的三维文字制作教程文档&#xff0c;重点解决在产品模型上添加标识、说明文字时如何生成空心字并拉伸为三维实体的问题&#xff0c;属于入门到进阶之间的实操型技能资料。压缩包共1个文件&#xff0c;为doc格式文档&am…

作者头像 李华
网站建设 2026/11/4 2:44:01

Easysearch 布尔查询子句重排序(二)|ConjunctionDISI 按 cost 排序源码解析

Lucene 如何让最稀疏的迭代器领跑&#xff0c;最大化跳过无效文档 INFINI Easysearch 是一款专注于企业级场景的分布式近实时搜索与分析引擎。它以 Apache Lucene 为内核进行了增强&#xff0c;在保持与行业主流搜索协议及开发生态完全兼容的同时&#xff0c;重点强化了安全性、…

作者头像 李华
网站建设 2026/11/4 2:43:41

指令调优入门:从LLaMA 7B微调看模型如何学会听话

简介&#xff1a;面向大语言模型指令微调方向的学习者与研究者&#xff0c;这份资源围绕 Stanford Alpaca 展开&#xff0c;即由 Meta LLaMA 7B 经指令调优得到的 instruction-following 模型&#xff0c;帮助读者理解如何借助 self-instruct 方式生成的 52K 指令样本完成微调训…

作者头像 李华