Spring Boot + MyBatis-Plus + Vue 家电维修系统实战:从环境搭建到工单流转与权限控制

发布时间:2026/11/5 3:01:00
Spring Boot + MyBatis-Plus + Vue 家电维修系统实战:从环境搭建到工单流转与权限控制

简介:这是一套面向Java全栈开发者与计算机专业学生的家电家具维修系统完整项目源码,基于SpringBoot、Mybatis-Plus与Vue.js技术栈构建,覆盖用户管理、订单提交、维修工单调度、在线支付、评价反馈及统计报表等业务模块,可用于课程设计、毕业设计或全栈项目实战练习。资源包共2009个文件,以1234个md文档、710个js脚本、47个json配置为主,另含sql建表脚本、html页面与docx项目说明,压缩包约60.36MB,目录按前后端与文档分层组织,便于按模块查阅。已有137人学习下载。读者可从中获取完整的前后端分离工程结构、数据库设计脚本、接口与组件实现代码,以及项目介绍文档,适合对照理解SpringBoot自动配置、Mybatis-Plus持久层操作与Vue组件化开发的落地方式,也可作为二次开发与功能扩展的参考基础。

1. 家电维修系统这套 Spring Boot + MyBatis-Plus + Vue 组合,到底能落地到什么程度

上周有个做本地家电售后的小团队找我,说他们现在接单全靠微信群和 Excel,师傅报修、配件库存、客户回访三张表对不上,月底结算能吵一下午。他们想要一套能自己跑起来、能改、能交付给师傅用的维修管理系统,预算不高,也不想被 SaaS 按年费绑死。我翻了几套开源方案,最后落到这套 Spring Boot + MyBatis-Plus + Vue 的家电家具维修系统上——前后端分离、权限体系完整、工单流转和配件库存都覆盖到了,代码结构对二次开发友好,不是那种只能看不能改的演示壳子。

这套东西适合谁?一是中小维修服务商想自建工单系统,二是计算机专业做课程设计或毕业设计需要一套能讲清楚业务链路的完整项目,三是想练手 Spring Boot 分层架构和 Vue 后台管理模板的开发者。它解决的核心问题不是「能不能跑」,而是「工单从报修到结算这条链路,数据怎么不丢、状态怎么不乱」。下面我按自己拆包、跑通、改配置的顺序讲,参数和坑都摊开说。

2. 环境搭建与依赖版本对齐:先让项目在你机器上活过来

拿到一个前后端分离的包,第一件事不是急着点启动,而是把版本矩阵对齐。这套系统后端是 Spring Boot 打底、MyBatis-Plus 做持久层,前端是 Vue 加后台管理模板,三块各自的版本如果错位,报错信息往往指向莫名其妙的地方,排查起来就是黑匣子。

2.1 后端依赖与 JDK 版本确认

先看pom.xml里的父工程版本和 JDK 编译级别。常见做法是 JDK 8 或 JDK 11 二选一,Spring Boot 2.x 系列对这两个都兼容,但如果你本机装的是 JDK 17,部分老版本的反射和字节码处理会直接抛异常。我一般先执行一遍版本检查再动手:

# 确认本机 JDK 版本,输出应为 1.8.x 或 11.x java -version # 确认 Maven 可用,建议 3.6 以上 mvn -v

如果 JDK 是 17 而项目父工程写的是 2.5.x 这类版本,别硬扛,装一个 JDK 8 或 11 切过去,比改一堆兼容配置省事。Maven 依赖拉取慢的话,在settings.xml里配国内镜像源,这一步不做,后面mvn clean install能卡到你怀疑网络。

依赖里重点看三样:MyBatis-Plus 的 starter 版本、数据库驱动版本、以及有没有引入 JWT 或 Sa-Token 这类鉴权组件。MyBatis-Plus 3.4 和 3.5 在分页插件配置上有差异,3.5 之后分页拦截器要显式注册MybatisPlusInterceptor,如果包里的配置类还是老写法,分页会静默失效——查出来永远是全量数据,这种坑不报错,最容易被忽略。

2.2 数据库初始化与连接配置

后端跑起来的前提是库先建好。包里一般带一个.sql脚本,导入之前先看一眼字符集,utf8mb4是必须的,家电型号、客户备注里出现特殊符号不至于乱码。导入命令按你用的客户端来,命令行方式如下:

# 创建数据库并指定字符集 mysql -u root -p -e "CREATE DATABASE repair_db DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;" # 导入表结构与初始数据 mysql -u root -p repair_db < ./sql/repair_db.sql

导入完检查两张关键表:用户权限表和工单主表。前者决定你登录后能看到哪些菜单,后者决定工单流转的字段是否齐全。然后改application.yml里的数据源配置,四个参数必须对上:url、username、password、driver-class-name。MySQL 8 的驱动类是com.mysql.cj.jdbc.Driver,连接串要带时区和是否用 SSL 的参数,常见写法是jdbc:mysql://localhost:3306/repair_db?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false。时区不配,插入时间字段会差 8 小时,工单创建时间全错,后面按时间统计直接翻车。

2.3 前端依赖安装与接口地址对接

前端进目录先装依赖,npm install或yarn都行,看包里锁文件是哪个。装完别急着npm run serve,先去配置文件里找接口基地址,通常在vue.config.js的代理配置或者.env文件里。后端默认端口 8080,前端开发服务器一般 8081 或 9528,跨域靠代理转发:

// vue.config.js 中的代理配置示例 module.exports = { devServer: { port: 8081, proxy: { '/api': { target: 'http://localhost:8080', // 后端实际地址 changeOrigin: true, pathRewrite: { '^/api': '' } // 按后端实际路径前缀调整 } } } }

pathRewrite这一行最容易配错。后端接口如果本身带/api前缀,这里就不能再重写掉,否则请求全 404。判断方法很简单:浏览器 F12 看请求的实际 URL,和后端 Controller 上的@RequestMapping对一遍,对不上就改这里。前后端都起来后,先用管理员账号登录,能进首页说明链路通了,再逐个点菜单验证接口。

3. 工单流转与权限体系:业务主链路怎么跑通

这套系统真正的价值在工单状态机,不在增删改查。报修、派单、上门、维修、结算,每一步状态变更都牵着客户表、师傅表、配件表,任何一处事务没兜住,数据就会对不上。这一章讲清楚主链路怎么设计、权限怎么卡、以及二次开发时该动哪里。

3.1 工单状态机与核心表结构

工单主表一般有这么几个关键字段:工单号、客户 ID、设备类型、故障描述、指派师傅 ID、状态、创建时间、完成时间。状态值常见是待派单、已派单、维修中、待结算、已完成、已取消。状态流转不能靠前端传什么就存什么,必须在服务层做校验,比如「已完成」不能再回退到「维修中」,否则结算数据会重复计算。

MyBatis-Plus 在这里的用法是实体类继承BaseMapper,条件构造器写查询。工单列表按状态和师傅筛选的典型写法:

// 工单分页查询,按状态与师傅 ID 过滤 LambdaQueryWrapper<RepairOrder> wrapper = new LambdaQueryWrapper<>(); wrapper.eq(RepairOrder::getStatus, status) // 状态精确匹配 .eq(RepairOrder::getWorkerId, workerId) // 师傅过滤 .orderByDesc(RepairOrder::getCreateTime); // 按创建时间倒序 Page<RepairOrder> page = new Page<>(pageNum, pageSize); repairOrderMapper.selectPage(page, wrapper);

LambdaQueryWrapper的好处是字段名走方法引用,改字段名编译期就报错,比字符串拼字段安全。Page对象的分页要生效,前提是前面说的分页拦截器注册对了,这是新手最容易漏的一环。状态变更接口建议单独写一个updateStatus方法,入参带工单 ID 和目标状态,方法内先查当前状态,用枚举或常量做合法流转判断,再更新,别让前端直接调通用的 update 接口改状态字段。

3.2 基于角色的菜单与接口权限

权限这块通常是用户、角色、菜单三张表加关联表。登录后后端返回 token,前端存起来,每次请求带在 header 里,后端拦截器解析 token 拿到用户角色,再决定接口放不放行。菜单权限靠角色关联的菜单 ID 动态生成路由,接口权限靠注解或拦截器校验。

二次开发时最常改的是给「师傅」角色单独收窄权限:师傅只能看指派给自己的工单,不能看全部。这个不能只在前端隐藏菜单,后端查询必须带上当前登录用户的 ID 做过滤,否则改个请求参数就能越权看到别人的单子。常见做法是从 token 解析出用户 ID,在服务层强制拼进查询条件,而不是信任前端传的师傅 ID。这一点在交付给外部使用时尤其要盯住,权限漏洞比功能缺失严重得多。

3.3 配件库存与工单的联动扣减

维修过程换配件,库存要扣,工单要记明细,这两步必须在一个事务里。典型流程是:工单进入维修中,师傅提交更换配件清单,系统校验库存是否充足,充足则扣库存、写工单配件明细表、更新工单状态。任何一步失败整体回滚。

// 配件扣减与工单明细写入,同一事务内完成 @Transactional(rollbackFor = Exception.class) public void consumeParts(Long orderId, List<PartItem> items) { for (PartItem item : items) { // 乐观锁或行锁扣减,防止并发超卖 int affected = partMapper.deductStock(item.getPartId(), item.getQty()); if (affected == 0) { throw new BizException("配件库存不足:" + item.getPartId()); } orderPartMapper.insert(buildDetail(orderId, item)); } orderMapper.updateStatus(orderId, OrderStatus.REPAIRING); }

deductStock的 SQL 要写成UPDATE part SET stock = stock - #{qty} WHERE id = #{id} AND stock >= #{qty},靠数据库行锁保证并发下不超卖,返回影响行数为 0 就说明库存不够。@Transactional的rollbackFor一定要写Exception.class,默认只回滚运行时异常,业务里抛的受检异常不回滚,库存扣了单子没记,这种账最难对。

4. 避坑与排查:跑这套系统时我踩过的几个真坑

4.1 分页查出来永远是全量数据

现象是列表页显示总条数不对,翻页没效果,每页都返回所有记录。原因是 MyBatis-Plus 3.5 之后分页插件换了注册方式,老配置类里的PaginationInterceptor已经废弃,新写法要注册MybatisPlusInterceptor并加PaginationInnerInterceptor。解决方法是找到配置类,按当前版本重写拦截器注册,重启后看 SQL 日志里有没有LIMIT关键字,有就对了。

4.2 登录后菜单空白但接口能通

现象是能登录、能拿到 token,但左侧菜单一片空白。原因多半是前端路由动态生成时,后端返回的菜单树结构和前端解析的字段名对不上,比如后端返回children前端读childList。解决方法是 F12 看菜单接口的返回 JSON,和前端路由生成那段代码逐字段比对,改字段映射或改后端 VO,别两边都改。

4.3 时间字段差 8 小时

现象是工单创建时间比实际早或晚 8 小时,按日期统计全错位。原因是数据库连接串没配serverTimezone,或者实体类时间字段用了Date而数据库是datetime且时区不一致。解决方法是在连接串加serverTimezone=Asia/Shanghai,实体类统一用LocalDateTime,Jackson 序列化配置时区,三处对齐后时间就稳了。

4.4 前端打包后刷新页面 404

现象是开发环境正常,npm run build部署到服务器后,首页能开,一刷新子路由就 404。原因是前端用的是 history 路由模式,服务器没配 fallback。解决方法是在 Nginx 里加try_files $uri $uri/ /index.html;,让所有未匹配路径回落到入口文件。这个坑和代码无关,纯部署配置,但交付时十有八九会遇到。

4.5 配件扣减偶发负数库存

现象是压测或多人同时提交时,库存出现负数。原因是扣减逻辑先查再改,两条 SQL 之间没有锁。解决方法是改成单条带条件的 UPDATE,靠stock >= qty做原子判断,或者用乐观锁版本号。别用「查出来判断再更新」的写法,并发下必翻车。

5. 二次开发与交付验证:把演示项目改成能用的系统

这套包拿来直接交付是不现实的,业务字段和本地流程一定对不上,关键是知道改哪里、怎么验证改对了。我的习惯是先跑通一条完整工单链路做基线,再动代码。

5.1 用一条完整工单做回归基线

改任何业务逻辑之前,先手工走一遍:新建客户、报修建单、派单给师傅、师傅接单、提交配件、完成维修、结算。每一步记下数据库里对应表的变化,形成一份基线记录。改完代码再走一遍,对比差异。这个笨办法能挡住大部分「改 A 坏 B」的问题,比事后查日志快得多。

5.2 关键接口的参数与返回校验

交付前用接口工具把核心接口过一遍,重点看三类:分页接口的总数和页大小是否生效、状态变更接口传非法状态是否被拦截、越权请求(用师傅账号查别人工单)是否返回空或拒绝。下面这张表是我一般会列的检查项:

检查项预期结果不通过时的排查方向
工单分页总数正确、每页条数受限分页拦截器是否注册
非法状态流转返回业务错误码服务层状态校验是否缺失
师傅越权查询只返回本人工单查询条件是否强制拼用户 ID
配件并发扣减库存不为负扣减 SQL 是否原子
时间字段与服务器时间一致连接串时区与序列化配置

5.3 交付前的配置外置与日志

最后一步是把数据库密码、接口地址这类环境相关配置从代码里挪到外部配置文件或环境变量,别把生产密码写死在application.yml里跟着代码走。日志级别调到INFO,关键业务操作(派单、扣库存、结算)打上操作人和时间,出问题时能顺着日志还原现场。做完这些,这套系统才算从「能跑」变成「敢交付」。

从那以后我每次拆这类前后端分离的维修系统,都先把版本矩阵和分页拦截器这两处确认一遍再动手,省下的排查时间比什么都值。希望帮到你。

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