☰
智慧家政系统毕业设计:SpringBoot+Vue+小程序三端联调实战解析
2026/10/18 12:27:35 网站建设 项目流程

简介:这是一套基于微信小程序和Java技术栈的智慧家政系统毕业设计源码,采用Vue配合SpringBoot与MySQL实现,面向需要完成毕设的计算机专业学生,以及想学习前后端分离架构的开发者。压缩包共409个文件,大小1.9MB,包含161个Java后端文件、72个Vue页面和72个JavaScript逻辑文件,另有微信小程序所需的WXML/WXSS、配置文件、数据库脚本与说明文档,结构清晰可快速导入主流IDE。其中Java文件对应后端业务与接口,Vue文件支撑管理后台页面,JS文件负责前端交互,WXML/WXSS用于小程序界面,模块划分明确。目前已有543人学习/下载。系统覆盖地址管理、订单管理、家政分类、家政服务、用户反馈等核心业务模块,并内置用户、部门、角色、菜单、日志、数据字典、文件管理等基础功能,实现基于角色的权限控制且可细化到按钮级别,便于自定义角色并分配权限。通过阅读源码可掌握SpringBoot后端接口设计、Vue前端数据绑定及小程序端交互流程,适合作为毕业设计、课设项目或企业级权限管理开发的参考方案。

1. 智慧家政系统毕业设计:这份源码到底能拿来做什么

做毕业设计最怕的是一套系统要管三个端:微信小程序给用户下单,Vue 后台给管理员排单,Java 后端用 SpringBoot 把数据串起来,MySQL 负责存所有业务数据。这套智慧家政源码正好把三端链路完整打通了,不是只有几个页面的半成品,而是带着用户、订单、家政分类、家政服务、用户反馈这些真实业务模块,外加一套基于角色的权限控制,权限能精确到按钮级别。如果你需要的是一个能直接跑、能讲清业务逻辑、还能支撑答辩演示的毕业设计项目,或者说想学 Vue + SpringBoot + 小程序三端联调的新手,这套资源比你自己从零搭省下大量时间。它既能当毕设主体,也能当二次开发基座。

2. 技术栈与系统架构:SpringBoot+Vue+小程序三端如何串联

这套系统不是单机 demo,而是典型的前后端分离 + 移动端接入结构。后端用 SpringBoot 提供 REST 接口,管理后台用 Vue 做单页应用,用户端则是一套独立的微信小程序。数据统一落在 MySQL,权限模型采用基于角色的访问控制,所以从架构上就能拆成三层,每一层都有独立部署路径。

2.1 后端 SpringBoot 与 MyBatis Plus:数据访问层的开箱即用

后端选 SpringBoot 是毕业设计最常见的组合,但数据访问层直接用 MyBatis Plus 是这套源码里比较省事的设计。它对单表 CRUD 做了封装,不用写 XML Mapper,Service 层也能直接继承 IService 拿到常用方法——这对你快速理解和上手源码特别友好。

下面是一段家政分类实体的真实写法,对应的就是系统里的分类管理模块:

// 家政分类实体(对应表:housekeeping_category) @Data @TableName("housekeeping_category") public class Category { @TableId(type = IdType.AUTO) private Long id; private String name; private Long parentId; private Integer sort; private Integer status; // 1-启用 0-禁用 @TableLogic private Integer deleted; }

逻辑说明:@TableName 指定了实体对应的数据表;@TableId 配置了主键自增策略;@TableLogic 标记 deleted 字段为逻辑删除。这样调用 MyBatis Plus 的 deleteById 时,实际执行的是 update 语句把 deleted 置为 1,而不是物理删除,能保住订单和反馈这类历史数据。parentId 是分类树的关键,根节点用 0 表示,子分类指向父分类的 id。

Service 层写起来也非常简洁:

@Service public class CategoryServiceImpl extends ServiceImpl<CategoryMapper, Category> { // 直接用 save/update/list/page 完成大部分操作,不需要手写 SQL }

为什么选 MyBatis Plus 而不是 JPA 或原生 MyBatis?核心原因是毕业设计要展示 CRUD,自己写 Mapper XML 会占大量篇幅,评审更关注业务逻辑设计。这套源码里用户管理、部门管理、日志管理都依赖这个封装,你读代码时能明显感受到单表操作被简化了,但复杂查询还是可以通过 LambdaQueryWrapper 自由构造条件,灵活性并没有丢。

2.2 Vue 管理后台与小程序端:接口调用与数据流

管理后台用的是 Vue + axios,小程序端用的是 wx.request,两者共用同一个后端接口,但请求封装方式不一样。

先看 Vue 端的请求封装:

// 管理后台请求封装(axios 实例) import axios from 'axios' const request = axios.create({ baseURL: '/api', timeout: 10000 }) request.interceptors.request.use(config => { const token = localStorage.getItem('token') if (token) { config.headers['Authorization'] = 'Bearer ' + token } return config }) export default request

逻辑说明:baseURL 写成 /api,是因为 Vue 开发服务器通过代理把 /api 开头的请求转发到后端端口,这样浏览器就不会跨域。拦截器负责在每次请求头上带上 token,后端接口通过 token 解析当前用户和角色权限,按钮级权限就是靠这个 token 里的角色信息判断的。

小程序端没法配置代理,必须写完整地址:

// 小程序 request 封装(wx.request) function request(url, data = {}, method = 'GET') { return new Promise((resolve, reject) => { wx.request({ url: getApp().globalData.baseUrl + url, method: method, data: data, header: { 'Authorization': 'Bearer ' + wx.getStorageSync('token') }, success: res => resolve(res.data), fail: err => reject(err) }) }) }

这段代码的关键是 baseUrl 单独放在全局变量里,你真机调试时改成电脑的局域网 IP 就行。token 存在 wx.getStorageSync 里,每次请求带着它,后端才能识别出到底是管理员还是普通消费者。开发阶段微信开发者工具可以勾选“不校验合法域名”,但真机预览时必须在微信公众平台配置合法请求域名,这个我在第 5 章避坑区会专门讲。

2.3 MySQL 表结构:从业务需求反推数据设计

从资源包里的 SQL 脚本能看到,核心表基本围绕两个使用者:后台管理员和前端用户。我整理了一张精简版表清单:

表名作用关键字段
sys_user系统用户表username, password, role_id
address用户地址表user_id, contact, phone, detail
housekeeping_category家政分类表name, parent_id, status
housekeeping_service家政服务表category_id, title, price, status
order订单表order_no, user_id, service_id, address_id, status
feedback用户反馈表user_id, content, status

关系很清晰:address 挂在 sys_user 下面,housekeeping_service 挂在 category 下面,order 同时关联 user、service、address。但订单表里通常还会存一份地址快照字段,也就是把下单那一刻的地址原文冗余到订单里,否则用户后来改了地址,历史订单的收货信息也会跟着变,这是做订单类系统很容易翻车的地方。这套源码里刻意做了快照设计,你看到订单表里的 address_snapshot 字段就能明白这个思路。所有业务表都带 deleted 字段做逻辑删除,因为订单和反馈涉及售后追溯,物理删掉就是事故。

3. 核心业务模块拆解:订单、家政服务、反馈链路

看完架构,再深入到业务模块。这套系统的业务链路其实很典型:用户选分类 → 选服务 → 填地址 → 下单 → 后台接单 → 服务完成 → 用户反馈。每一环都有对应的代码支撑,下面按模块拆开看。

3.1 家政分类与服务的上下架管理

分类是树形结构,前端管理后台要展示一棵可展开的树。常见做法是在内存里组装,避免递归查询数据库:

// 查询分类树:先一次性查出全部,再按 parentId 组装成树 List<Category> list = categoryService.list(); Map<Long, List<Category>> group = list.stream() .collect(Collectors.groupingBy(Category::getParentId)); List<Category> tree = buildTree(group, 0L);

逻辑说明:group 按 parentId 分组后,根节点的 parentId 是 0,buildTree 从根开始递归拼接子节点,最后返回一棵完整的分类树。参数 parentId 决定层级,sort 字段控制分类显示顺序。运维管理员在后台调整分类是否上架,通过 status 字段控制,用户端小程序只拉取 status=1 的分类和小程序端只展示启用状态的服务。

服务表独立存在,每个服务挂在一个分类下面,后台可以对服务单独做上下架。这个上下架状态有点像电商里的商品开关,禁用后用户端立刻看不到,但历史订单不受影响,因为订单里存的是服务快照(价格、名称都冗余了一份)。这种设计能顶住“服务价格调整后,老订单要不要跟着变”的质疑,答辩时是一个不错的细节。

3.2 订单状态流转与地址绑定

订单是这套系统的核心业务对象。状态流转可以用一张表讲清楚:

状态值含义后续动作
0待接单管理员接单
1已接单进入服务中
2服务中完成服务
3已完成可评价/完结
4已取消交易结束

创建订单的 Service 代码大致是这样的:

@Transactional public Order createOrder(OrderDTO dto) { Address addr = addressService.getById(dto.getAddressId()); Order order = new Order(); order.setOrderNo(genOrderNo()); order.setUserId(dto.getUserId()); order.setServiceId(dto.getServiceId()); order.setAddressSnapshot(addr.getProvince() + addr.getDetail()); order.setStatus(0); orderService.save(order); return order; }

这里 @Transactional 保证了整个下单过程要么全成功,要么全失败。addressSnapshot 是把地址拼成文本存入订单,这样用户后续在地址簿里改了信息,这笔订单仍然保留原始服务地址。genOrderNo 是生成唯一订单号的工具方法,常见做法是日期时间 + 随机数,避免并发下重复。很多新手会忽略地址快照,直接只存 address_id,后面真改地址就出现旧订单跟着变的诡异问题,这里提前给你打了预防针。

3.3 用户反馈与后台处理闭环

用户端小程序里有一个“意见反馈”入口,用户提交的内容落进 feedback 表,后台管理系统里有对应的反馈列表页。查询反馈列表非常依赖条件构造器:

// 反馈列表查询:按处理状态筛选,超时未处理的排前面 public Page<Feedback> page(Integer status, Integer pageNum, Integer pageSize) { LambdaQueryWrapper<Feedback> wrapper = new LambdaQueryWrapper<>(); wrapper.eq(status != null, Feedback::getStatus, status) .orderByAsc(Feedback::getStatus) .orderByDesc(Feedback::getCreateTime); return feedbackService.page(new Page<>(pageNum, pageSize), wrapper); }

eq 方法第一个参数是布尔条件,status 为 null 时自动跳过这个条件,不需要手动 if 判断。orderByAsc(Feedback::getStatus) 让待处理的反馈排在最上方,orderByDesc(Feedback::getCreateTime) 按最新反馈优先展示。后台管家在处理反馈时把状态从“待处理”改成“已处理”,用户端如果写了“我的反馈列表”,就能看到处理进度。这个模块虽然简单,但能形成前后台数据闭环,毕设里算是一个功能完整的亮点。

4. 部署与运行:从零跑通这套系统的七个步骤

这套源码拿到手后,最快跑通的路径是:先初始化数据库,再启动后端,然后启动 Vue 管理后台,最后用微信开发者工具打开小程序端。下面按步骤拆解,每一步都带上命令和参数说明。

4.1 环境准备:JDK、Maven、MySQL、小程序工具

需要准备的环境:JDK 1.8 或 11,Maven 3.6+,MySQL 5.7+(建议 8.0 也兼容),Node.js 12+,微信开发者工具。后端是 SpringBoot 2.x 的话,JDK 8 完全够用,不需要上 17。如果你本机装的是 JDK 11,也能跑,但注意 Maven 的 compiler 插件版本要支持。

建议用 MySQL 8.0 时把驱动改成 com.mysql.cj.jdbc.Driver,并在 jdbc URL 上加上 serverTimezone=Asia/Shanghai,否则时间字段会报时区错。这个细节很多人只在第一次启动时才会遇到。

4.2 后端启动与数据库初始化

先建库,再导入 SQL 脚本:

mysql -uroot -p -e "CREATE DATABASE housekeeping DEFAULT CHARACTER SET utf8mb4;" mysql -uroot -p housekeeping < sql/housekeeping.sql

说明:字符集必须用 utf8mb4,不能用 utf8,因为小程序端会传用户备注、地址详情这种可能带表情符号的文本,utf8mb4 才能存下 4 字节字符。sql 目录里的 housekeeping.sql 是这份源码自带的初始化脚本,执行完后会创建全部表,并且写入一批初始数据,包括分类、服务、测试账号和菜单权限数据。

然后修改 application.yml 里的数据源连接:

spring: datasource: url: jdbc:mysql://localhost:3306/housekeeping?useUnicode=true&characterEncoding=utf8mb4&serverTimezone=Asia/Shanghai username: root password: 你的密码

改完密码就能启动后端:

cd backend mvn spring-boot:run

看到“Started Application”日志就说明后端起来了。如果你用 IDE 导入 Maven 项目,也可以直接运行启动类的 main 方法。

4.3 Vue 管理后台启动

管理后台是标准的 Vue 工程:

cd frontend npm install npm run dev

npm install 如果速度很慢,可以考虑设置镜像源,这不是必须的,但能省时间。启动后打开 http://localhost:9528(端口取决于源码里的 vue.config.js),就能看到登录页。

这里有个常见配置——开发代理。Vue 端页面请求的地址是 /api,为了不跨域,vue.config.js 里需要这样配置:

module.exports = { devServer: { proxy: { '/api': { target: 'http://localhost:8080', changeOrigin: true } } } }

这样 /api/xxx 会被转发到后端的 8080 端口。注意:如果你后端改过端口,这里的 target 也要同步改。

4.4 小程序端运行与联调

用微信开发者工具导入源码包中的小程序目录(一般是 miniapp 或 wxapp 文件夹),第一次打开会提示“未配置合法域名”,开发阶段不管,直接在开发者工具右上角点击“详情 → 本地设置”,勾选“不校验合法域名、web-view(业务域名)、TLS 版本以及 HTTPS 证书”。

然后修改小程序里的接口地址。找到 utils/request.js 或 config.js,把 baseUrl 改成开发机实际可达的地址:

// 小程序端全局请求地址 let baseUrl = 'http://localhost:8080' // 真机调试时改成电脑局域网 IP,例如 http://192.168.1.100:8080

改完后保存,在开发者工具里点击编译,就能看到小程序首页。先用用户账号登录,随便下一单,再回到管理后台看订单状态,如果能看到新增订单,说明三端已经完全联通。

第 4 步跑通后,你再用默认管理员账号登录管理后台,进去把“家政分类”“家政服务”“用户反馈”几个菜单挨个点一遍,确认数据能正常展示和操作,这套系统就完整落地了。这一步不要跳过,因为后续的二次开发全部建立在“三端已通”这个前提下。

5. 避坑指南:从源码到运行最常见的五个坑

这节写的都是我自己在部署类似源码时踩过的坑,每条按“现象 → 原因 → 解决”的思路整理,你按步骤跑到哪一步出错,直接对号入座。

5.1 建表脚本执行报“外键不存在”

  • 现象:导入 housekeeping.sql 时提示 “Cannot add foreign key constraint”,脚本中断。
  • 原因:表之间有外键依赖,但脚本里建表顺序不对——先建了子表,再建父表,导致外键关联失败。
  • 解决:如果是 MySQL 5.7,可以临时关闭外键检查,导入完再开启。在脚本最前面加一行 SET FOREIGN_KEY_CHECKS=0;脚本末尾加 SET FOREIGN_KEY_CHECKS=1。如果你用的是 MySQL 8.0,也可以先手动调整表顺序,或者直接忽略外键——因为这套系统正常开发模式不需要物理外键,业务层已经通过逻辑关联保证完整性,删掉外键反而更省心。

5.2 小程序请求失败,提示“url not in domain list”

  • 现象:在微信开发者工具里编译时接口正常,但一用真机预览,所有请求全失败,后台日志显示请求根本没到达后端。
  • 原因:微信小程序真机环境强制要求请求域名必须在公众平台配置,localhost 或局域网 IP 不在合法域名列表里。
  • 解决:纯开发和演示阶段,在开发者工具里勾选“不校验合法域名”即可;但如果你想在自己手机上体验完整流程,需要把后端部署到公网,并在公众平台配置 HTTPS 域名。这里特别提醒:不要为了省事把 request 合法域名留空,预览环节一定会翻车。

5.3 管理员登录后菜单空白,页面打不开

  • 现象:用项目自带的管理员账号登录后台,页面能打开,但侧边栏菜单不显示,或者点击菜单显示空白页。
  • 原因:账号的角色没有分配菜单权限,或者 sys_menu 表里的菜单数据被破坏。这套系统的权限模型是按钮级 RBAC,菜单列表是后端根据角色动态返回的,不是前端写死的。
  • 解决:先确认 sys_menu 表里有没有初始化数据;然后用超级管理员账号进入“角色管理”,给当前角色勾选相应菜单和按钮权限,保存后刷新页面。注意:不要直接改数据库角色关联表,因为按钮权限是多表关联,手工改容易漏。

5.4 上传的图片前台显示不了

  • 现象:在管理后台给家政服务上传图片,保存成功,但小程序端图片裂开,后台的列表页图片也显示 404。
  • 原因:SpringBoot 默认不把本地磁盘路径映射成静态资源 URL。数据库里存的是 /upload/xxx.jpg,但根本没有对应的请求处理器去磁盘上找文件。
  • 解决:加一个静态资源映射配置类:
@Configuration public class WebConfig implements WebMvcConfigurer { @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/upload/**") .addResourceLocations("file:" + uploadPath + "/"); } }

uploadPath 在配置文件里定义,路径末尾一定要带 /。Windows 下写 file:E:/upload/,Linux 下写 file:/home/app/upload/。这个配置补齐后,重启后端,图片路径就能正常访问。

5.5 后端启动时 Redis 连接失败

  • 现象:后端启动到一半,控制台报 “Unable to connect to Redis”,然后进程退出。
  • 原因:源码默认开了 Redis 缓存,但你的本机没有安装或没有启动 Redis 服务。
  • 解决:两个方案任选。方案一是安装并启动 Redis,本地也可以直接用 Docker 起一个容器;方案二是把源码里的缓存逻辑改成简单实现,比如去掉 @EnableCaching 或者把 RedisTemplate 换成本地 Map 缓存。毕业设计如果不需要演示缓存,第二个方案更省事,因为少装一个中间件,答辩时也更容易解释。改完后要先 clean 再重新编译,不然旧配置会残留。

6. 进阶玩法:用代码生成模板快速扩展新模块

这套源码包里除了业务代码,还带了一组模板文件,像 tree.btl、add.btl、edit.btl、mpController.btl、mpServiceImpl.btl、api.btl 这些。它们的作用是批量生成增删改查代码——把给定表的字段定义喂给模板,就能自动生成 Controller、Service、Mapper、Vue 列表页和编辑页。我第一次用这套源码时只顾着改业务,完全没理模板,后来想加一个“售后服务”模块,手写了五个文件,花掉半天。等意识到模板的存在,重新跑一次生成流程,二十分钟就搞定了。

如果你想在答辩里展示扩展能力,可以按这个思路操作:

第一步,先看模板目录里 entity.btl 和 mpController.btl 的内容,把里面的示例字段(比如 id、name、status)替换成你要新增模块的字段。比如做一个“服务评价”模块,字段就是订单号、评分、评价内容、评价时间。

第二步,在数据库建一张对应表,表名用 evaluation,字段和模板里定义的一致,注意主键策略、逻辑删除字段这些也要对齐。

第三步,运行源码里的代码生成入口,输入表名和模块名,系统会依据模板自动生成代码。生成后,把新增的 Controller、Service、实体类放到对应的包路径下,前端生成的文件放到 views 目录。

第四步,验证两步:先启动后端,用管理后台的菜单管理添加一个“评价管理”菜单,绑定到新生成的页面路径;再用小程序端调新增的提交评价接口,看数据能不能写进 evaluation 表。这里可以用 SWagger 或直接调试工具测接口,确认新增模块没有破坏原有权限配置。

我一般还会额外跑一遍原有流程做回归测试——用不同角色登录后台,看看新菜单是否按角色显示,确保按钮级权限没有漏配。这套模板的学习成本不高,真正掌握后,你等于给自己的毕设加了一个“快速开发任意模块”的可演示能力,比在答辩时翻半天代码强得多。

那次手写文件踩了模板的坑之后,我每次拿到新的源码包,都会先花半小时翻目录,专门找有没有模板和生成脚本,再决定是手写还是自动生成。希望帮到你。

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

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询