2026/10/30 17:22:14

SpringBoot+微信小程序家政服务与互助平台毕设源码跑通与二次开发指南

SpringBoot+微信小程序家政服务与互助平台毕设源码跑通与二次开发指南 简介这份资源是面向高校计算机相关专业毕业设计的完整项目包围绕微信小程序家政服务与互助平台展开适合需要完成毕设、课程设计或想学习小程序全栈开发的学生与开发者。压缩包共883个文件约40.81MB以Java源码、SVG与PNG图片、JS脚本、WXSS与WXML小程序页面、Vue组件、JSON配置及SQL脚本为主另附PPT演示文稿与MP4演示视频覆盖后端接口、前端页面、数据库与答辩材料。项目后端采用Spring Boot框架与Java语言开发结合MySQL实现数据管理前端融合HTML、CSS、JavaScript与Vue.js构建交互界面功能涵盖家政服务浏览预约、订单提醒、服务记录追踪、评价分享、家政员个人中心管理以及帖子互助社区等模块。已有64人学习下载读者可据此获得一套可直接运行参考的完整源码、数据库脚本与演示视频便于快速理解项目结构、梳理功能实现思路并用于答辩展示。1. 家政服务与互助平台从一份毕设源码里拆出能跑通的落地路径每年毕业季总有一批同学拿着「基于 SpringBoot 后端 微信小程序的家政服务与互助平台」这类题目来找我问的无非是同一件事这套东西到底能不能跑起来、能不能改成自己的、答辩时会不会被老师问穿。我见过太多人把源码包解压完就卡在第一步——后端启动报错、小程序连不上接口、数据库表对不上号。这个标题背后其实是一套非常典型的「SpringBoot 做服务端 微信小程序做用户端」的双端架构核心业务是家政服务的下单、接单、评价外加一个互助模块让用户之间互相帮忙。它适合两类人一是拿它当毕设底稿、需要快速跑通并做二次开发的学生二是想用一套完整案例练手 SpringBoot 接口设计和微信小程序页面联调的开发者。接下来我不讲空话直接按「环境怎么搭、接口怎么写、小程序怎么连、坑在哪」的顺序把这套东西拆到你能照着复现的程度。2. 环境搭建与项目结构把 SpringBoot 后端和微信小程序前端同时跑起来2.1 后端技术选型与依赖版本确认拿到源码第一步不是急着点运行而是先看pom.xml里的 SpringBoot 版本。热搜词里「springboot版本太高」是真实高频问题——很多毕设源码写的时候用的是 2.7.x你本地 IDEA 默认拉 3.x一启动就报jakarta.servlet找不到或者javax.annotation被移除。我一般会先把版本锁死再动其他配置。!-- pom.xml 关键依赖版本按源码实际调整 -- parent groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-parent/artifactId version2.7.18/version !-- 不要盲目升到3.xjavax→jakarta迁移会炸 -- relativePath/ /parent dependencies !-- Web 层提供 REST 接口给小程序调用 -- dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependency !-- MyBatis-Plus家政订单、用户、服务类目表的 CRUD 全靠它 -- dependency groupIdcom.baomidou/groupId artifactIdmybatis-plus-boot-starter/artifactId version3.5.3.1/version /dependency !-- MySQL 驱动 -- dependency groupIdmysql/groupId artifactIdmysql-connector-java/artifactId version8.0.33/version /dependency !-- JWT小程序登录后签发 token 用 -- dependency groupIdio.jsonwebtoken/groupId artifactIdjjwt/artifactId version0.9.1/version /dependency /dependencies这段依赖里最容易被忽略的是 MyBatis-Plus 和 SpringBoot 的版本匹配。3.5.3.1 配 2.7.x 是稳的如果你把 SpringBoot 升到 3.2MyBatis-Plus 得换 3.5.5 以上否则启动时SqlSessionFactory注入失败。JWT 用 0.9.1 是因为它依赖javax.xml.bind在 JDK 11 以上需要额外加jaxb-api否则签 token 时抛NoClassDefFoundError。我一般会在pom.xml里补上dependency groupIdjavax.xml.bind/groupId artifactIdjaxb-api/artifactId version2.3.1/version /dependency参数上spring-boot-starter-parent的版本决定了整个项目的基线不要为了「用新特性」去动它。数据库连接池默认 HikariCP连接数在application.yml里配maximum-pool-size: 10就够毕设场景用调大了反而在低配机器上启动慢。2.2 数据库建表与初始数据导入源码包里一般会带一个.sql文件但很多人导入时只导了结构没导数据结果小程序首页服务列表是空的还以为接口写错了。我习惯先确认三张核心表user用户含微信 openid、service_item家政服务类目比如保洁、月嫂、维修、order订单含状态字段。互助模块通常再加一张help_request表。-- 建库字符集必须 utf8mb4否则微信昵称里的 emoji 存进去变问号 CREATE DATABASE housekeeping DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; -- 服务类目表小程序首页列表就查这张 CREATE TABLE service_item ( id BIGINT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(64) NOT NULL COMMENT 服务名称如日常保洁, price DECIMAL(10,2) NOT NULL COMMENT 单价, cover_img VARCHAR(255) COMMENT 封面图URL, status TINYINT DEFAULT 1 COMMENT 1上架 0下架 ) ENGINEInnoDB DEFAULT CHARSETutf8mb4; -- 订单表状态机是答辩必问点 CREATE TABLE order ( id BIGINT PRIMARY KEY AUTO_INCREMENT, user_id BIGINT NOT NULL, service_id BIGINT NOT NULL, status TINYINT DEFAULT 0 COMMENT 0待接单 1已接单 2已完成 3已取消, create_time DATETIME DEFAULT CURRENT_TIMESTAMP, remark VARCHAR(255) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;导入顺序是先建库、再建表、最后插初始数据。初始数据至少给service_item插 5 条否则小程序首页wx:for渲染出来是空白你会误以为请求没发出去。order表的status字段用数字而不是字符串是为了后面做状态流转判断时少写if直接比大小。注意order是 MySQL 关键字建表时必须加反引号查询时也要加否则报语法错误。2.3 微信小程序端项目导入与域名配置小程序端用微信开发者工具打开导入时选源码包里的miniprogram目录。导入后第一件事是改app.js里的baseUrl指向你本地后端地址。这里有个高频翻车点微信开发者工具默认校验合法域名你填http://localhost:8080会报「不在以下 request 合法域名列表中」。// app.js App({ globalData: { // 本地调试用局域网IP不要用 localhost真机预览连不上 baseUrl: http://192.168.1.100:8080, userInfo: null, token: }, onLaunch() { // 启动时检查本地是否有 token有就跳过登录 const token wx.getStorageSync(token) if (token) { this.globalData.token token } } })baseUrl必须写你电脑的局域网 IP因为手机预览时localhost指向手机自己。获取 IP 用ipconfigWindows或ifconfigMac。然后在开发者工具右上角「详情」→「本地设置」里勾上「不校验合法域名、web-view业务域名、TLS 版本以及 HTTPS 证书」这一步是本地调试的后悔药不勾后面所有请求都发不出去。正式上线才需要备案域名和 HTTPS毕设阶段不用管。3. 核心接口开发家政下单、接单与互助模块的 SpringBoot 实现3.1 微信登录换 openid 与 JWT 签发小程序端wx.login()拿到 code传给后端换 openid这是整个用户体系的入口。很多源码在这里写死了 appid 和 secret你直接跑会报invalid appid得去微信公众平台申请自己的测试号或者用源码作者留的。RestController RequestMapping(/api/auth) public class AuthController { Value(${wx.appid}) private String appid; Value(${wx.secret}) private String secret; Autowired private UserService userService; PostMapping(/login) public Result login(RequestBody LoginDTO dto) { // 1. 用 code 换 openid这里用 RestTemplate 调微信接口 String url https://api.weixin.qq.com/sns/jscode2session ?appid appid secret secret js_code dto.getCode() grant_typeauthorization_code; ResponseEntityString resp new RestTemplate().getForEntity(url, String.class); JSONObject json JSON.parseObject(resp.getBody()); String openid json.getString(openid); if (openid null) { return Result.fail(微信登录失败 json.getString(errmsg)); } // 2. 查库没有就注册 User user userService.getByOpenid(openid); if (user null) { user new User(); user.setOpenid(openid); user.setNickname(dto.getNickname()); userService.save(user); } // 3. 签发 JWT过期时间 7 天 String token JwtUtil.sign(user.getId(), 7 * 24 * 3600); return Result.ok(token); } }appid和secret放在application.yml里不要硬编码进 Java 文件否则你提交代码时泄露了还得去重置。jscode2session接口返回的openid是用户唯一标识session_key不要存数据库它只是解密用的临时密钥。JWT 的过期时间设 7 天是因为毕设演示周期短设太长有安全风险设太短你每次调试都要重新登录。JwtUtil.sign里 payload 只放 userId不要放昵称头像那些从数据库查。3.2 家政服务列表分页与小程序加载更多热搜词里「微信小程序页面列表加载更多」是高频需求家政服务列表、订单列表都要用。后端用 MyBatis-Plus 的分页插件前端用onReachBottom触底加载。GetMapping(/list) public Result list(RequestParam(defaultValue 1) Integer page, RequestParam(defaultValue 10) Integer size) { // MyBatis-Plus 分页Page 对象直接传给 mapper PageServiceItem p new Page(page, size); LambdaQueryWrapperServiceItem wrapper new LambdaQueryWrapper(); wrapper.eq(ServiceItem::getStatus, 1) // 只查上架的 .orderByDesc(ServiceItem::getId); serviceItemMapper.selectPage(p, wrapper); return Result.ok(p.getRecords(), p.getTotal()); }// 小程序端 pages/service/list.js Page({ data: { list: [], page: 1, hasMore: true }, onLoad() { this.loadData() }, loadData() { if (!this.data.hasMore) return wx.request({ url: getApp().globalData.baseUrl /api/service/list, data: { page: this.data.page, size: 10 }, success: (res) { const records res.data.data this.setData({ list: this.data.list.concat(records), page: this.data.page 1, // 返回条数小于 size 说明到底了 hasMore: records.length 10 }) } }) }, onReachBottom() { this.loadData() } })后端Page对象的page从 1 开始不是 0传 0 会返回空列表。前端hasMore判断用records.length 10如果后端返回的 total 和 records 不一致以 records 长度为准。onReachBottom在页面滚动到底部 50px 内触发如果列表没撑满一屏它不会触发所以首次加载后要判断list.length 10就直接设hasMore: false。3.3 订单状态流转与互助请求的接单逻辑订单状态机是答辩老师最爱问的待接单→已接单→已完成中间不能跳。互助模块的help_request类似但多一个「求助者确认完成」的环节。Transactional PostMapping(/accept/{orderId}) public Result accept(PathVariable Long orderId, RequestAttribute Long userId) { Order order orderMapper.selectById(orderId); // 状态必须是 0 待接单否则不允许接 if (order null || order.getStatus() ! 0) { return Result.fail(订单状态不允许接单); } // 不能接自己发的单 if (order.getUserId().equals(userId)) { return Result.fail(不能接自己的订单); } order.setStatus(1); order.setAcceptUserId(userId); orderMapper.updateById(order); return Result.ok(); }Transactional必须加因为接单可能涉及扣减接单人的接单次数或者更新用户积分两步操作要么都成功要么都回滚。RequestAttribute Long userId是从拦截器里取的拦截器解析 JWT 后把 userId 塞进 request这样每个接口不用重复解析 token。状态判断用! 0而不是 1因为未来可能加「已取消」状态用不等于待接单更稳。4. 联调与部署把本地跑通的项目放到服务器上演示4.1 前后端联调的三个必查项本地联调时接口 404、跨域、token 失效是三大拦路虎。404 先看RequestMapping路径和前端url拼出来的是否一致注意baseUrl结尾不要带/接口路径开头要带/。跨域在 SpringBoot 里加配置类Configuration public class CorsConfig implements WebMvcConfigurer { Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping(/**) .allowedOriginPatterns(*) // 用 patterns 不用 origins否则带 cookie 时报错 .allowedMethods(GET, POST, PUT, DELETE) .allowCredentials(true) .maxAge(3600); } }allowedOriginPatterns是 SpringBoot 2.4 以后的新写法用allowedOrigins(*)配合allowCredentials(true)会抛异常。token 失效先看请求头有没有带Authorization小程序端要在wx.request的header里手动加不会自动带。4.2 打包部署到服务器的最小步骤毕设演示一般用云服务器把 SpringBoot 打成 jar 包用nohup后台跑。# 1. 本地打包跳过测试否则测试用例连不上数据库会失败 mvn clean package -DskipTests # 2. 上传 jar 到服务器 scp target/housekeeping-0.0.1-SNAPSHOT.jar root你的服务器IP:/opt/app/ # 3. 服务器上后台启动日志输出到 nohup.out nohup java -jar /opt/app/housekeeping-0.0.1-SNAPSHOT.jar --spring.profiles.activeprod /opt/app/nohup.out 21 # 4. 看日志确认启动成功 tail -f /opt/app/nohup.out-DskipTests必须加因为很多毕设源码的测试类写死了本地数据库连接服务器上跑测试会卡住。--spring.profiles.activeprod指定生产配置application-prod.yml里数据库地址改成服务器内网地址。nohup后面的21把错误流也重定向到日志不然报错你看不到。小程序端baseUrl改成服务器公网 IP 加端口微信开发者工具里勾选「不校验合法域名」依然有效。5. 避坑与排查这套源码跑不起来时先看这五条5.1 启动报Table xxx doesnt exist现象SpringBoot 启动成功但一调接口就报 SQL 异常提示表不存在。原因数据库连上了但没建表或者建表语句里的库名和application.yml里配的不一致。解决先确认application.yml的url里库名再进 MySQL 执行use 库名; show tables;没有就重新导.sql。注意.sql文件里如果有CREATE DATABASE语句导入时可能建了新库你连的还是旧库。5.2 小程序请求返回request:fail url not in domain list现象开发者工具里请求发不出去控制台报域名不合法。原因没勾选「不校验合法域名」。解决详情→本地设置→勾选不校验。如果勾了还报检查baseUrl是不是https开头但服务器没配证书本地调试统一用http。5.3 登录后其他接口返回 401现象登录接口正常返回 token但调订单接口提示未授权。原因前端没把 token 放进请求头或者后端拦截器路径配错了。解决在小程序wx.request的header里加Authorization: Bearer token后端拦截器excludePathPatterns里要放行/api/auth/**否则登录接口本身也被拦。5.4 订单列表分页第二页数据重复现象上拉加载后列表出现重复项。原因后端分页page从 0 开始传了或者前端page没自增。解决确认后端new Page(page, size)的page从 1 开始前端每次加载后page 1并且用concat而不是直接赋值。5.5 打包后 jar 启动报no main manifest attribute现象java -jar提示没有主清单属性。原因pom.xml里没配spring-boot-maven-plugin。解决在build节点加插件配置重新mvn package。注意插件版本要和 SpringBoot 版本一致2.7.x 用 2.7.18。6. 从能跑到能答辩三个让老师眼前一亮的改造技巧第一把订单状态流转做成可视化。小程序端用wx:if根据status渲染不同按钮后端加一个/api/order/timeline/{id}接口返回状态变更记录答辩时演示「待接单→已接单→已完成」的完整链路比干讲代码有说服力。第二互助模块加一个简单的信用分机制用户完成一次互助加 1 分接单时优先展示高分用户这个改动只涉及user表加一个credit字段和查询时orderByDesc但能体现你对业务的理解。第三把application.yml里的敏感配置抽到环境变量演示时用--wx.appidxxx启动说明你知道生产环境不能把密钥写死在代码里。// 信用分加分的实现放在订单完成接口里 Transactional PostMapping(/finish/{orderId}) public Result finish(PathVariable Long orderId) { Order order orderMapper.selectById(orderId); if (order.getStatus() ! 1) return Result.fail(状态不对); order.setStatus(2); orderMapper.updateById(order); // 接单人信用分 1 User acceptUser userMapper.selectById(order.getAcceptUserId()); acceptUser.setCredit(acceptUser.getCredit() 1); userMapper.updateById(acceptUser); return Result.ok(); }我自己的习惯是每次改完一个模块就用 Postman 把相关接口全跑一遍确认返回结构和前端预期一致再动下一块。毕设最怕的就是改到后面忘了前面最后联调时一堆接口对不上。这套源码的价值不在于它多完美而在于它给了你一个能跑通的骨架你往里面填自己的业务逻辑就行。希望帮到你。本文还有配套的精品资源点击获取