简介面向微信小程序毕业设计场景这套家政服务管理系统完整覆盖用户预约、支付、评价以及管理员对家政公司、阿姨、服务项目和留言的管理流程。项目采用微信开发者工具构建小程序前端SSM框架Java开发管理后台MySQL5.7存储业务数据适合作为课程设计或毕业设计的参照与二次开发基础。压缩包共1142个文件约17.26MB其中wxml/wxss/js对应小程序页面逻辑vue/java/json/xml构成管理端与后端工程png/svg/jpg为界面素材另含2个sql脚本和install/run/build批处理文件方便直接部署。目前已有135人学习资料内含完整前后端源码、数据库文件、环境说明及常见IDE/容器配置可帮助快速跑通项目并理解微信小程序SSMMySQL的典型实现。1. 家政服务管理系统这套Java小程序源码值不值得拿来改毕业设计选微信小程序方向的同学大概率会搜到这套“家政服务管理系统”源码包——Java写后端、微信小程序写前端、MySQL存数据外加一份LW文档。它解决的不是什么高深技术难题而是毕设最常见的痛点表结构怎么设计、前后端怎么对接、演示流程怎么走通。这套代码的技术含量不算高但完整度够能让一个零基础的人在两三天内把项目跑起来再改两三个模块变成自己的东西。适合三类人Java方向想省时间的、小程序方向缺后端的、想看看一个O2O服务类项目完整长什么样的。不适合纯抄不改的人——这个选题在高校里撞车率不低答辩时被问深一点很容易露馅。2. 拆包看三层小程序页面、Java接口与MySQL表的对应关系2.1 拿到压缩包先看什么目录结构与三层对应一套能跑起来的毕设源码结构一定是有迹可循的。这套家政服务管理系统的标准骨架是后端一个Spring Boot工程、小程序端一个原生小程序工程、根目录一个sql脚本和一个LW目录。解压后先在资源管理器里过一遍骨架心里有数再动手。jiazheng-server/ # Java后端Spring Boot工程 src/main/java/com/xxx/ controller/ # 接口层接收小程序HTTP请求 service/ # 业务层下单、派单、支付回调都在这里 mapper/ # 数据库访问层MyBatis或MyBatis-Plus entity/ # 实体类对应MySQL表字段 config/ # 拦截器、跨域、静态资源映射 src/main/resources/ application.yml # 端口、数据源、MyBatis配置 mapper/ # MyBatis XML文件 pom.xml # 依赖清单先看Spring Boot版本 jiazheng-miniapp/ # 微信小程序前端 pages/ index/ # 首页、服务项目列表 order/ # 下单、订单列表 user/ # 个人中心 login/ # 微信登录页 utils/ request.js # wx.request统一封装 app.js # 全局配置baseUrl、token、用户信息 sql/ jiazheng.sql # 建库建表测试数据最关键的启动文件 LW/ LW.docx # LW即论文/设计文档答辩前按它准备拿到包先核对这个骨架缺sql脚本说明数据库得自己手搓工作量翻倍小程序端缺pages目录说明这是个残废包。靠谱的毕设源码一定同时包含这三样——后端代码能编译、sql脚本能导入、小程序能编译运行缺一样都别浪费时间。2.2 小程序端request封装与登录态小程序端最核心的两个文件是 app.js 和 utils/request.js。request.js 负责所有HTTP请求的进出app.js 负责全局状态。先看请求封装因为后面所有页面调接口都走这一个文件改接口地址、加token、处理登录过期都在这里集中处理不用每个页面写一遍wx.request。// utils/request.js所有页面统一走这里改接口地址不用逐个页面找 const BASE_URL http://localhost:8080/api function request(url, method GET, data {}) { return new Promise((resolve, reject) { wx.request({ url: BASE_URL url, method: method, data: data, header: { Content-Type: application/json, // 登录后拿到的token每次请求自动带上后端靠它识别用户 token: wx.getStorageSync(token) || }, success: (res) { // 后端统一返回结构 { code: 200, msg: ok, data: {...} } if (res.data.code 200) { resolve(res.data.data) } else if (res.data.code 401) { // token失效清掉本地缓存跳回登录页重新登录 wx.removeStorageSync(token) wx.redirectTo({ url: /pages/login/login }) } else { wx.showToast({ title: res.data.msg || 请求失败, icon: none }) reject(res.data) } }, fail: (err) { wx.showToast({ title: 网络异常, icon: none }) reject(err) } }) }) } module.exports { request }BASE_URL 在本地联调时写 localhost到了真机预览必须改成电脑在局域网里的IP这是毕设联调里最常见的翻车点。token 从 Storage 取每次请求塞进 header后端拦截器统一校验——这套模式在毕业设计里出现率极高几乎每个Java小程序的项目都长这样。登录态的逻辑也不复杂小程序端先调 wx.login 拿到临时 code然后把 code 发给后端 /api/user/login后端拿 code 去微信服务端换 openid再生成一个 token 返回给小程序小程序把它存进 Storage后续请求都带这个 token 就行。openid 是微信用户在你这套系统里的唯一身份用它做 user 表的主键关联比让用户自己注册账号方便得多。2.3 Java后端统一返回体与分层接口后端是标准的 Spring Boot 三层结构Controller 接收请求、Service 写业务逻辑、Mapper 操作数据库。所有接口的返回值都统一走一个 Result 包装类前端拿到后只判断 code就能决定是正常处理还是弹错误提示。// 统一返回体所有接口都返回这个结构小程序端只用判断code public class ResultT { private Integer code; // 200成功401未登录500业务或系统错误 private String msg; private T data; public static T ResultT success(T data) { ResultT r new Result(); r.code 200; r.msg ok; r.data data; return r; } public static T ResultT error(Integer code, String msg) { ResultT r new Result(); r.code code; r.msg msg; return r; } // getter/setter 省略 }Controller 层拿到的业务数据经过 Service 处理后返回给小程序的典型写法如下。注意 token 是从请求头里取的不是从参数里传这是校验登录身份的常规做法。RestController RequestMapping(/api/order) public class OrderController { Autowired private OrderService orderService; // 用户下单接收服务项目id、预约时间、地址 PostMapping(/create) public ResultInteger create(RequestBody OrderCreateDTO dto, RequestHeader(token) String token) { Integer userId orderService.getUserIdByToken(token); if (userId null) { return Result.error(401, 登录已过期); } int orderId orderService.createOrder(userId, dto); return Result.success(orderId); } }RequestHeader(token) 从请求头拿登录标识RequestBody 接收小程序传来的JSON对象。如果后端是 MyBatis-Plus 写的Service 层通常直接继承 ServiceImplMapper 继承 BaseMapper单表增删改查基本不用写SQL。毕设选 MyBatis-Plus 的最大好处是省时间orderMapper.insert(order) 一行就完成插入不用像原生 MyBatis 那样手写 insert 语句再配 XML。2.4 数据库表设计与业务字段这套系统的表结构是典型的O2O服务类项目设计五张核心表就能撑起整个业务闭环。看懂了这几张表你就看懂了整个系统的设计思路。表名核心字段说明userid, openid, nickname, phone小程序用户身份openid是微信唯一标识workerid, name, avatar, service_type, score家政服务人员service_type关联服务分类service_itemid, name, cover, price, unit, description服务项目如日常保洁、家电清洗orderid, order_no, user_id, worker_id, item_id, order_status, appoint_time, address, remark订单主表状态机核心evaluationid, order_id, user_id, star, content服务评价让业务形成闭环订单表里的 order_status 是整个系统最关键的字段一般用 int 存储。这套项目里常见的枚举是0待支付、1待接单、2服务中、3待评价、4已完成、5已取消。用 int 而不是 varchar 的原因很简单排序和查询方便配合常量类可读性也够。答辩时十有八九会被问“为什么用数字不用字符串”答案就是上面这句再加一句“状态流转逻辑集中在Service层不会到处散落魔法值”。2.5 核心链路从下单到完成的状态流转下单接口是业务的核心入口它的逻辑开了好头生成订单号、设置初始状态为待支付、预约时间和地址落库。支付成功后状态从0变成1进入待接单后台管理员或者家政人员接单后状态改成2服务中服务完成改成3待评价用户评价完改成4已完成。每次状态变更前都先查一次当前状态不是目标状态直接拒绝这套流程能挡住大部分并发乱序操作。public int createOrder(OrderCreateDTO dto, Integer userId) { Order order new Order(); order.setOrderNo(generateOrderNo()); // 自定义单号yyyyMMdd 随机数 order.setUserId(userId); order.setItemId(dto.getItemId()); order.setWorkerId(0); // 先不指派人员接单后再写 order.setOrderStatus(0); // 0待支付初始状态 order.setAppointTime(dto.getAppointTime()); order.setAddress(dto.getAddress()); order.setCreateTime(new Date()); orderMapper.insert(order); return order.getId(); } // 支付成功后回调状态0改为1进入待接单 public boolean paySuccess(Integer orderId) { Order order orderMapper.selectById(orderId); if (order null || order.getOrderStatus() ! 0) { return false; // 订单不存在或状态不对直接拒绝 } order.setOrderStatus(1); return orderMapper.updateById(order) 0; }generateOrderNo 的生成规则直接决定订单号是否可读常见做法是日期加随机数比如 202506011530001234前端展示时也直观。paySuccess 里的状态判断就是数据一致性最简单也最实用的实现——不做校验直接 update极容易出现状态错乱已取消的订单还能“支付成功”变成待接单这在答辩演示时是硬伤。3. 把整套源码跑起来从JDK、MySQL到微信开发者工具的全链路启动3.1 版本匹配先定JDK和Spring Boot别盲升拿到源码第一时间不是双击跑而是看 pom.xml 里 Spring Boot 的版本再决定用什么JDK。这套毕设最常见的组合是 Spring Boot 2.x JDK 1.8 或 11。Spring Boot 3.x 要求 JDK 17但大量老毕设依赖的 MyBatis-Plus 版本不兼容照搬新教程反而卡启动。组件推荐版本说明JDK1.8 或 11Spring Boot 2.x 必须JDK17容易遇到依赖不兼容Maven3.6.x 或 3.8.x拉依赖稳定3.9也可以MySQL5.7 或 8.08.0需要改认证插件和连接参数Spring Boot2.5 ~ 2.7看pom.xml别轻易升3.x微信开发者工具稳定版本地调试勾选“不校验合法域名”提示先看 pom.xml 再装环境这是拿到任何毕设源码后的第一件事。Spring Boot 2.5 和 2.7 的配置写法有差异以你包里的实际版本为准。MySQL 5.7 和 8.0 的选择上建议直接看你 sql 脚本里的建表语句如果用了 utf8mb4 和 InnoDB 默认配置两个版本都能跑如果脚本里有老式 ENGINEMyISAM 或者字段类型很古早用 5.7 更稳。不要在一个翻车率高的环节上给自己加戏。3.2 初始化数据库SQL脚本导入与MySQL 8认证插件数据库初始化是第一个容易卡住的环节。最简单的方式是命令行直接导入也可以打开 Navicat 在对应库上运行 sql 脚本。# 在MySQL bin目录下执行或直接让Navicat运行sql文件 mysql -uroot -p sql/jiazheng.sql如果用的 MySQL 8.x导入完成后大概率遇到 JDBC 连接报错提示信息通常是“Public Key Retrieval is not allowed”或者“Unable to load authentication plugin”。原因是 MySQL 8 默认的认证插件是 caching_sha2_password而老版本 JDBC 驱动不认识它。解决方法是把 root 用户的认证方式改回旧版-- MySQL 8.x下JDBC连不上时先执行这段把认证插件改成旧版 ALTER USER rootlocalhost IDENTIFIED WITH mysql_native_password BY 你的密码; FLUSH PRIVILEGES;这个坑在毕设阶段命中率极高尤其那些从网上下载的源码包自带 JDBC 驱动还是 5.x 的情况下。改完认证插件再用命令行试一下 mysql -uroot -p 能进接下来才轮到改后端配置。3.3 后端配置与启动application.yml里四个必改参数数据源配置是后端跑起来的命门打开 src/main/resources/application.yml重点核对 url、username、password 这三行。四个必改参数记清楚端口、库名、用户名、密码。任何人下载的源码包都不会写你的本地密码这一步必须自己改。server: port: 8080 spring: datasource: url: jdbc:mysql://localhost:3306/jiazheng?useSSLfalseserverTimezoneAsia/ShanghaicharacterEncodingutf8mb4 username: root password: 123456 driver-class-name: com.mysql.cj.jdbc.Driver mybatis-plus: mapper-locations: classpath:mapper/*.xml configuration: map-underscore-to-camel-case: trueuseSSLfalse 用来关掉 MySQL 8 的 SSL 握手不写的话控制台会刷一堆 SSL 警告个别版本直接连接失败。serverTimezoneAsia/Shanghai 是必须的漏了它订单时间会差八个小时。characterEncodingutf8mb4 解决中文乱码因为 MySQL 8 默认字符集是 utf8mb4。改完配置启动方式二选一IDEA 里点运行主类或者命令行执行 mvn spring-boot:run。启动完成后不要急着开小程序先用浏览器或 curl 验证后端接口通没通。# 能返回JSON数组说明数据源和Mapper都没问题 curl http://localhost:8080/api/service/list这一步能省大量时间——后端通了再开小程序联调出问题定位范围小一半。我见过同学后端没起来就直接编译小程序结果界面上所有数据都是空的排查了半天才发现是 Spring Boot 启动失败。3.4 小程序端导入AppID、本地设置与baseUrl微信开发者工具里选“导入项目”目录指向 jiazheng-miniappAppID 用测试号即可不需要注册自己的小程序。导入成功后第一件事是改 app.js 里的 BASE_URL把 localhost 换成后端地址。// app.js本地联调写localhost真机预览改成电脑在局域网里的IP const BASE_URL http://localhost:8080/api module.exports { BASE_URL }同时检查右上角“详情 → 本地设置”勾选“不校验合法域名、web-view业务域名、TLS版本以及HTTPS证书”。这个选项就是本地调试的后悔药不勾的话小程序请求任何 http 接口都会报错“url not in domain list”。正式上线才需要配合法域名本地开发必须开着它。3.5 联调走查从登录到下单的完整验证前后端都启动后按照真实用户的路径走一遍流程。顺序是固定的登录 → 浏览服务列表 → 选择服务项目 → 提交订单填地址和预约时间→ 模拟支付 → 查看订单状态变化 → 后台接单 → 服务完成 → 评价。在每个步骤之间观察数据和状态是否正确发现问题立刻停下排查不要赶着往下走。完整走查前先做一个快速冒烟测试浏览器开两个标签一个调后端登录接口拿token一个调服务列表接口确认接口能返回数据。后端没问题再进小程序点界面否则会把前端问题误判成后端问题。这套“先接口后界面”的排查顺序是联调阶段效率最高的方法。4. 改造成自己的毕设二次开发最值得动的四个模块4.1 首页分类与推荐位改造一眼可见的区别纯跑通原版源码答辩时老师一眼就能看出是下载的。改首页是最低成本的做法服务项目的分类、价格、封面图全部在数据库里你会 mysql 的 update 语句就能改。思路是把原本的“日常保洁、家电清洗、管道疏通”换成自己设计的一组分类再配一组有实际含义的推荐语。-- 换一组分类让首页第一屏看起来和原版不同 UPDATE service_item SET name 深度保洁, price 199.00 WHERE id 1; UPDATE service_item SET name 空调清洗, price 159.00 WHERE id 2; UPDATE service_item SET description 全屋除尘厨房去油污卫生间除垢 WHERE id 1;改完数据库首页的加载逻辑不用动。如果嫌分类不够多在 service_item 表里直接 INSERT 几行新数据注意 cover 字段要填图片地址——可以是本地静态资源路径也可以放一张网络图片。做完这一步首页展示的内容和下载包已经完全区分开答辩时讲故事的开场就有了。4.2 新增评价模块让业务闭环更完整原版项目如果只做到订单完成业务就中断了答辩切入点不多。加一个评价功能把“下单→服务→评价”串成完整闭环话题一下就多了。实现也不复杂一张新表加两个接口就能跑。CREATE TABLE evaluation ( id int NOT NULL AUTO_INCREMENT, order_id int NOT NULL COMMENT 订单id, user_id int NOT NULL COMMENT 评价人, star tinyint DEFAULT 5 COMMENT 1~5星评分, content varchar(500) DEFAULT NULL COMMENT 评价内容, create_time datetime DEFAULT NULL, PRIMARY KEY (id), KEY idx_order (order_id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;后端加一个 EvaluationController前端在订单完成后弹一个评价弹窗。打分用小程序原生的星星组件或者简单的 radio-group 加点CSS就行——顺带说一句小程序里的单选框radio-group在原生组件里算好调的绑定一个 change 事件拿到值直接提交。这个模块做完你的系统从功能上看就比原版多了一个独立业务模块答辩时可讲的内容多了一大块。4.3 登录拦截器让接口不再裸奔很多免费下载的毕设源码有一个通病后端接口完全裸奔不带 token 也能访问。这个漏洞答辩时被问到会很难堪“你的系统怎么保证只有登录用户能下单”解决办法是加一个 Spring Boot 拦截器统一校验请求头里的 token。public class LoginInterceptor implements HandlerInterceptor { Autowired private UserService userService; Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String token request.getHeader(token); if (token null || userService.getUserIdByToken(token) null) { response.setStatus(401); response.setContentType(application/json;charsetUTF-8); response.getWriter().write({\code\:401,\msg\:\未登录\}); return false; } return true; } }再在 WebMvcConfig 里注册拦截器把 /api/order/、/api/user/info/这些需要登录的路径拦截起来。这个改动代码量不大但价值很高——既修复了安全漏洞又在答辩时多了一个“我考虑了接口安全”的亮点。4.4 缓存与本地存储token过期处理小程序的 token 存在 Storage 里如果永久不过期用户换了设备还能继续用旧 token逻辑上不严谨。常见做法是登录时同时存 token 和过期时间戳每次请求前判断是否过期。// 登录成功后的写缓存顺手记一个过期时间 wx.setStorageSync(token, res.data.token) wx.setStorageSync(tokenExpire, Date.now() 2 * 60 * 60 * 1000) // 2小时后过期request.js 里每次发起请求前检查一下 tokenExpire过期就清掉缓存并跳回登录页。这一条配合后端的 token 生成逻辑把“有效期”这个词在答辩时讲出来比单纯说“我做了登录功能”高级不少。注意这里的 token 只是控制访问时效真正要严谨还得在后端 JWT 里设置过期时间前端缓存属于双保险。5. 避坑指南从数据库连接到真机预览的六条踩坑记录5.1 MySQL连接类端口不通与SSL握手两个高频坑坑1后端启动时报 error 2002 (HY000) Cant connect to local MySQL server through socket /tmp/mysql.sock现象mvn spring-boot:run 后控制台刷出数据库连接失败错误码是 2002提示找 /tmp/mysql.sock 找不到。原因MySQL 服务根本没启动或者启动的不是你预期的那台实例。Linux 下常见Windows 下一般是服务没开。解决先确认 MySQL 进程在跑。Linux 用 systemctl status mysql 或 mysql -uroot -p 直接登一下Windows 打开服务管理器找到 MySQL 服务点启动。如果服务状态正常但 socket 路径不对在 /etc/mysql/mysql.conf.d/mysqld.cnf 里查 socket 路径或者干脆把 JDBC url 改成 127.0.0.1:3306 绕开 socket 文件。坑2连接MySQL 8时控制台报 SSL 相关错误重启或 DB 连接异常 Communications link failure现象能连通 MySQL 但日志里不断刷“SSL connection error”粗暴一点的版本直接报 Communications link failure程序起不来。原因MySQL 8 默认开了 SSL 加密连接而 JDBC 驱动版本或配置不匹配握手失败被当成致命错误。解决在 application.yml 的 url 后面加 useSSLfalse让连接不走 SSL 加密同时把驱动版本往上提用 mysql-connector-java 8.x 而不是 5.x。帽子一句话MySQL 8 配老驱动的组合必须有这个参数兜底不然就是随机翻车。5.2 小程序请求类域名校验和真机IP两个坑坑3小程序页面一直报“url not in domain list”所有接口请求失败现象编译正常但页面上任何请求都进不了 success 回调console 报错提示请求的 URL 不在合法域名列表。原因小程序天然不允许请求 http 接口更不认识 localhost。开发工具默认开了域名校验没有在后台配置 request 合法域名所有本地接口全被拦截。解决开发工具“详情 → 本地设置”里勾选“不校验合法域名、web-view业务域名、TLS版本以及HTTPS证书”。勾完重新编译即可。这是本地联调的前提不记下来每次新建项目都要踩一遍。坑4真机预览时后端请求全部失败开发工具里却一切正常现象点“真机调试”手机上的小程序能打开页面但所有数据加载不出来转圈转一圈就提示网络异常。原因手机访问不了你电脑上的 localhost。真机和小程序开发工具走的是两条网络路径localhost 指代的是手机自身而你的后端跑在电脑上手机需要访问电脑的局域网IP。解决把 app.js 里的 BASE_URL 改成电脑的局域网IP比如 http://192.168.1.5:8080/api并确保手机和电脑连同一个WiFi。顺手在防火墙里放行 8080 端口否则请求还是会被拦在电脑外面。改完之后在手机浏览器里直接访问 http://192.168.1.5:8080/api/service/list能出JSON再进小程序。5.3 业务数据类模拟支付后状态不更新坑5模拟支付成功订单状态却一直停留在0待支付现象小程序里点了“模拟支付”订单页刷新后状态还是待支付后台也没有收到任何状态变更。原因前端只调了支付模拟接口没调后端支付成功回调。很多毕设源码把支付成功处理放在后端 paySuccess 接口里前端漏掉这一步调用状态机就卡死在原地。解决顺着小程序端支付按钮的点击事件找到支付成功后的处理逻辑确认它是否请求了 /api/order/paySuccess 并把订单id传过去。如果源码里没有这个调用加上一行 request(/api/order/paySuccess, POST, { orderId: xxx }) 就能补上。这属于前后端流程没对齐的典型问题排查时先看前端有没有调对接口再查后端有没有正确处理。6. 交付前的最后一道工序自检清单与三个高频追问6.1 功能自检清单照着走一遍省得演示时翻车按下面的清单在演示环境完整走一遍每项符合预期才算过关。模块操作步骤预期结果登录小程序点微信登录能进首页个人中心显示微信昵称服务列表首页浏览服务项目展示分类、价格、封面图无裂图下单选服务填地址和时间提交生成订单状态为待支付模拟支付点击模拟支付按钮订单状态变为待接单接单后端或后台管理端接单订单状态变为服务中完成服务完成操作状态变为待评价评价提交评分和内容状态变为已完成评价列表可见这里面最容易出问题的是“模拟支付”很多源码的支付按钮就是个空壳没绑任何后端调用。演示前务必把这一环跑通它是最常被老师追问的环节。6.2 演示数据设计让现场不冷场演示最怕的是临时创建账号、临时下单结果接口返回报错或数据空白。提前把数据准备好是基本操作在数据库里插好几个服务项目配上清晰度高的封面图准备一个测试微信号提前登录好把 token 存进 Storage再预置两三条已完成订单让订单列表和评价列表打开就有内容不用现场等流程跑完。我第一次跑这种毕设源码时没先核对 MySQL 版本就卡了半个下午在 SSL 握手报错上。从那以后不管拿到谁的包我都强制走一遍“版本核对 → 数据库导入 → 接口自测 → 小程序联调”四步跑通了再动手改业务。希望帮到你。本文还有配套的精品资源点击获取