简介:面向 Java 小程序方向毕业设计与课程设计的上门维修系统完整源码,涵盖前台用户、维修员、管理员三大角色模块。用户端支持首页、广告信息、新闻资讯、个人中心及维修信息、维修记录、评价、收藏管理;维修员端可管理维修单与评价;管理员端包含用户、维修员、维修信息、维修记录、评价、广告及系统管理等后台功能。资源包共 1249 个文件,压缩包 26.06MB。其中 123 个 Java 源文件与 1 个 SQL 数据库脚本构成服务端,145 个 Vue 文件、226 个 JS 文件和 49 个 WXML/WXSS 文件组成小程序前后端,278 个 PNG、161 个 SVG 等素材用于界面与图标展示,并附带 Maven、Tomcat 等环境配置文件。已有 121 人学习下载,适合需要快速搭建完整可运行项目的毕业生,可基于现有模块进行功能扩展,也可作为理解小程序端与服务端交互、角色权限设计的参考范例。
1. 基于小程序的上门维修系统源码:三端闭环的 Java 毕设模板
交上一份能演示但不能跑通业务的毕设,答辩时被问倒的场面我没少见。最常见的翻车点是:用户端下单了,维修员端看不到单子;维修员改了状态,管理后台数据没同步。这份“基于小程序的上门维修系统源码”是一套能跑通业务闭环的三端工程:用户小程序、维修员小程序、PC 管理后台,外加 Java(SSM)后端服务。用户能提交维修申请、查记录、写评价、收藏;维修员能处理信息和记录;管理员在后台管用户、管维修员、管广告和系统配置。如果你正在做 java 毕业设计,或想给线下维修门店搭一个轻量接单入口,这套源码值得先跑一遍再谈改造。下文从压缩包结构、环境初始化、接口联调三个角度,拆解我实际把它跑起来的过程。
2. 压缩包结构:小程序前端、Vue 管理端与 Java 后端的分工边界
拿到压缩包先别急着点运行,第一步是把三端代码认清楚。这套源码不是单一项目,而是“小程序端 + 管理后台前端 + Java 服务端”三个工程打成一个包。三者各自负责一段业务,缺一个都会让功能链断掉。
2.1 小程序端:一套代码里跑用户和维修员两个身份
小程序工程里能看到app.json注册的首页、广告信息、新闻资讯、我的这几个 Tab 页。“我的”页面下面挂维修信息、维修记录、评价信息、我的收藏四个子页面。维修员端复用同一套框架,页面结构几乎一样,靠登录后返回的role字段切换身份,比如首页显示的是用户视角还是维修员视角。
以提交维修申请为例,维修类型用radio-group渲染成单选列表,用户选择后连同描述文本一起提交,走的是统一的请求封装:
// utils/request.js —— 小程序的网络请求封装 const baseUrl = 'http://localhost:8080/repair/'; function request(url, method, data) { return new Promise((resolve, reject) => { wx.request({ url: baseUrl + url, method: method || 'GET', data: data || {}, header: { 'Content-Type': 'application/json' }, success: (res) => resolve(res.data), fail: (err) => reject(err) }); }); } module.exports = request;和浏览器里用 axios 不一样,小程序wx.request走的是宿主环境提供的网络 API,不传success回调就拿不到返回值,所以这里包一层 Promise,调用方就能用await写同步风格。baseUrl必须写全协议、IP、端口和上下文路径,后端如果有 context-path 一定别漏。
我排查这类问题时的习惯是先把res.statusCode和res.data一起打印出来,只看响应体不看状态码,容易把 404 当成业务报错。后面第 5 章专门列了几个这类坑。
2.2 管理后台:IndexAsideStatic 侧边栏与 update-password 改密
管理后台部分能看到一组 Vue 文件:IndexMain.vue(主内容区)、IndexAsideStatic.vue(静态侧边栏)、IndexHeader.vue(顶栏)、BreadCrumbs.vue(面包屑)、update-password.vue(修改密码)。这是经典的管理后台布局:左侧导航菜单驱动右侧内容区,点用户管理、维修员管理、维修信息管理,都是往同一个IndexMain里塞对应路由组件。
update-password.vue单独说,是因为三个角色共用同一套改密逻辑:输入原密码、新密码、确认新密码,提交给后端接口。源码里这些页面带着.bak后缀的备份文件,比如IndexMain.vue.bak、update-password.vue.bak、main.js.bak,作用是保留改动前的稳定版本——改坏了,用copy命令把.bak覆盖回来就能回滚。我的习惯是拿到压缩包先把.bak和源文件对比一次,确认自己拿到的不是中途改坏的版本。
管理后台开发调试分两段走:本地用1-install.bat装 npm 依赖,2-run.bat起 dev 调试服务;交付时用3-build.bat打包静态文件,把 dist 目录交给后端。这三个脚本顺序不能乱,第 3 章会给出完整命令和参数说明。
2.3 Java 后端:Controller-Service-Mapper 对应一组管理对象
后端是标准 SSM(Spring + SpringMVC + MyBatis)工程。从功能清单能反推出来至少有 7 张业务表:用户表、维修员表、维修信息表、维修记录表、评价信息表、广告信息表、新闻资讯表。它们各自对应一组 Controller、Service、Mapper。
以“我的收藏”为例,用户收藏一条维修服务后,前端调用/user/favorite/save,Controller 只做参数接收和返回包装,真正的数据库操作落在 Service 和 Mapper 层:
@RestController @RequestMapping("/user") public class UserFavoriteController { @Autowired private UserFavoriteService favoriteService; @PostMapping("/favorite/save") public R save(@RequestBody Favorite favorite) { boolean saved = favoriteService.saveFavorite(favorite); return saved ? R.ok() : R.error("保存失败"); } }三层结构里,Controller 负责接参数,Service 负责业务判断比如“是否重复收藏”“用户是否存在”,Mapper 负责 SQL。这里的R是统一结果类,带code/message/data三个字段,前端所有接口都按这个结构判断成功失败。毕设里不要为省代码把业务逻辑堆在 Controller 里,答辩时这是高频扣分点。
2.4 数据表关系:维修信息与维修记录是核心链路
维修信息表和维修记录表是整个系统的命脉。用户提交的“维修申请”落在维修信息表,记录维修类型、问题描述、期望上门时间;维修记录表管状态流转——接单、上门、完成,每一步状态变更都追加一条记录,最终用户基于这条记录写评价。
| 表名 | 归属模块 | 核心字段 | 谁在写 |
|---|---|---|---|
| t_user | 用户管理 | id, username, password, phone, avatar | 用户注册、管理员维护 |
| t_repairer | 维修员管理 | id, real_name, phone, service_area, status | 管理员维护 |
| t_repair_info | 维修信息管理 | id, user_id, repair_type, description, appoint_time, status | 用户提交、维修员更新 |
| t_repair_record | 维修记录管理 | id, repair_id, repairer_id, operate_type, operate_time | 维修员 |
| t_evaluate | 评价信息管理 | id, repair_id, score, content, create_time | 用户 |
| t_advertisement | 广告信息管理 | id, title, image, link, sort, status | 管理员 |
| t_news | 新闻资讯管理 | id, title, content, cover, publish_time | 管理员 |
这样分表的好处是用户、维修员、管理员三个角色操作的数据域清晰:用户写维修信息,维修员写维修记录,管理员管基础数据和内容。权限判断落到“角色”上,而不是在页面里写死。理解了这张表关系,后面启动项目、看接口参数都会顺手很多。
3. 从 mysql 建库到三个 bat 脚本:把源码跑起来的前置操作
这一章做的是“从零到能跑”的初始化。整套流程我按数据库、后端、管理后台三步走,每一步都验证通过后再进下一步,避免最后一起报错分不清是谁的问题。
3.1 用 Navicat11 创建数据库并导入 repair.sql
数据库版本锁定 mysql 5.7,工具用 Navicat11 最顺手。先手动建一个 utf8mb4 字符集的库,名字建议和后端连接配置保持一致:
CREATE DATABASE IF NOT EXISTS repair_system DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;用 utf8mb4 而不是 utf8,是因为小程序端用户输入可能带 emoji 表情;用 utf8 在 5.7 里写入特殊字符会报Incorrect string value。建完库,打开 Navicat 左侧连接,右键数据库选“运行 SQL 文件”,把repair.sql导进去。导入时注意两点:
- 项目要求 mysql5.7,如果你本机装的是 mysql8,SQL 文件里可能有
utf8mb4_0900_ai_ci排序规则,5.7 不识别; - 导入完执行
show tables;,看到 7 张以上表才算完整。
我用 Navicat11 连 mysql8 时遇到过caching_sha2_password认证报错,那是 mysql8 默认加密插件变了。开发机装多版本 mysql 时,建议先跑一次环境检查再往下走,省得浪费半小时。
3.2 后端 SSM:IDEA 打开、Maven3.3 构建、Tomcat7 部署
后端工程用 IDEA 打开 pom.xml,Maven 会自动拉依赖。JDK 必须切到 1.8——我见过用 JDK11 编译javax.servlet相关代码直接失败的情况。部署容器选 Tomcat7,端口默认 8080,上下文路径建议设成/repair,这样后端接口地址就是http://localhost:8080/repair/...,和小程序 baseUrl 正好对齐。
mvn clean install -DskipTests这条命令的作用是跳过测试、把 war 包产出到 target 目录。为什么跳过测试?毕设工程的单元测试未必写全,直接跑集成测试会因为连不上数据库而中断,反而拖慢节奏。war 包生成后,在 IDEA 的 Tomcat 配置里指向它启动,日志出现Server startup in [...] milliseconds说明 Spring 容器加载成功。启动慢就先检查数据库连接池的密码和端口是否对齐。
3.3 管理后台三个 bat 脚本:安装、运行、构建
管理后台是 Vue 工程,压缩包里的.bat脚本是给不熟悉 npm 的人准备的。执行顺序就是名字前的数字顺序:
@echo off rem 1-install.bat —— 安装前端依赖 cd /d %~dp0 call npm install --registry=https://registry.npmmirror.com pause@echo off rem 2-run.bat —— 启动开发调试服务 cd /d %~dp0 call npm run dev pause@echo off rem 3-build.bat —— 打包生产静态文件 cd /d %~dp0 if exist dist rmdir /s /q dist call npm run build:prod pause第一段里--registry是国内镜像源,装 element-ui、vue-router 这些依赖比默认源快很多,不加这个参数,项目卡在 install 阶段的概率很高。第二段起 dev server,默认端口看工程里的vue.config.js,常见是 8080 或 9528,浏览器打开那个地址就能看到后台登录页。第三段把旧的 dist 清掉重新生成,后端部署时整个 dist 拖进 Tomcat 的 webapp 即可。
注意顺序千万别反:2-run.bat跑在1-install.bat之前,会直接报vite或webpack不是内部命令。改完代码后也要重新跑一次 build,否则线上看到的还是旧页面。
4. 小程序端联调:baseUrl、登录链路与 Network 排查
后端和管理后台跑起来,下一步就是把小程序端接到本地接口上。这一章是上手这套源码的核心操作,同时也是“小程序抓包”能派上用场的场景。
4.1 改 baseUrl:本机接口 vs 真机接口
小程序端代码里最常改的就是utils/request.js里的baseUrl。第 2 章给过模板,实际联调时区分两种情况:
- 微信开发者工具:直接写
http://localhost:8080/repair/,模拟器里没有跨域限制; - 真机预览:手机不能访问电脑的 localhost,要改成电脑的局域网 IP,比如
http://192.168.1.101:8080/repair/。
改完别只改一处,先搜全局有没有第二个 request 封装。有的工程在用户端、维修员端各抽了一个api.js,漏改的地方会表现为“首页正常,我的页面报错”。更稳的做法是把baseUrl收敛到单独 config 文件,用户端和维修员端都引用它,改一处全局生效。
4.2 登录链路:wx.login 换 token
小程序在微信环境里拿不到免密登录身份,只能用wx.login拿临时code换后端 token:
wx.login({ success: (res) => { const code = res.code; request('/wx/login', 'POST', { code }) .then((data) => { wx.setStorageSync('token', data.token); wx.setStorageSync('userInfo', data.userInfo); }); } });code有效期只有五分钟,且只能用一次。后端拿到 code 后调用微信接口换 openid 和 session_key,再生成自己系统的 token 返回。毕设里这一步经常被简化为“直接返回 token”,但你要知道前端参数名是 code,后端返回字段是 token。如果登录失败,先去 Network 面板看/wx/login的响应报文,再决定改前端还是后端。
4.3 用 Network 面板做接口排查
微信开发者工具的 Network 面板类似浏览器控制台,能看到每个请求的 URL、method、statusCode、响应体。按小程序抓包的思路,我排查顺序固定为四步:
- 看请求有没有发出——没发出说明按钮没绑定或逻辑报错;
- 看 statusCode——404 查 URL 和上下文路径,500 去后端日志;
- 看响应体里的 code——后端不认可基本是参数名对不上;
- 看耗时——超过 3 秒大概率是 SQL 缺索引或数据量问题。
这套排查对管理后台同样适用。后端日志和 Network 面板对照着看,十分钟能定位八成的联调问题。工具链摸熟之后,再看复现这套源码时最容易踩的坑。
5. 复现避坑实战:这五个坑几乎人人都遇到
5.1 request 合法域名校验
现象:小程序页面正常渲染,但所有请求直接失败,控制台提示“不在以下 request 合法域名列表中”。
原因:微信小程序生产环境要求请求域名必须备案并在后台配置合法域名。本地开发默认开启校验,域名是 localhost 自然通不过。
解决:打开微信开发者工具,右上角“详情 → 本地设置”,勾选“不校验合法域名、web-view(业务域名)、TLS 版本以及 HTTPS 证书”。这是本地调试最直接的办法。真机预览时,则要把后端部署到有备案域名和 HTTPS 证书的服务器上才能绕过。
5.2 后端上下文路径导致 404
现象:后端 Tomcat 启动成功,小程序端请求http://localhost:8080/user/favorite/save返回 404。
原因:后端部署时上下文路径是/repair,完整路径其实是http://localhost:8080/repair/user/favorite/save,baseUrl 漏写了上下文。
解决:在 IDEA 的 Tomcat 配置里查看 Application context 一栏,把 baseUrl 改成对应值。我验证路径的习惯是:本地浏览器直接访问完整接口,能返回 JSON 说明路径正确,再回小程序看结果。别在小程序端反复试错。
5.3 mysql 导入报 utf8mb4_0900_ai_ci
现象:Navicat 导入 SQL 文件时中断,报Unknown collation: 'utf8mb4_0900_ai_ci',或者表建了但数据行数为 0。
原因:SQL 文件是用 mysql8 导出的,5.7 不识别 mysql8 默认排序规则。
解决:用文本编辑器打开 SQL 文件,全局替换utf8mb4_0900_ai_ci为utf8mb4_general_ci。替换不影响数据内容只影响排序规则,导入后再show tables确认表和数据行数。
5.4 .bak 文件改错导致页面异常
现象:管理后台某个页面报“模块解析失败”,控制台错误定位到IndexMain.vue.bak,或代码里出现重复 export。
原因:.bak是文本备份,但构建工具会把 src 下所有.vue文件当源码解析。有人直接在.bak里改代码,保存后被构建工具扫描进来,导致重复导入或语法错误。
解决:.bak文件不应该留在 src 目录下,移到工程外的 backup 文件夹,或在打包配置里排除。想恢复旧版,用命令行copy update-password.vue.bak update-password.vue /y覆盖,再把.bak移出 src。任何情况下都不要在.bak里改代码,改完也不会被编译进去。
5.5 真机预览连不上后端
现象:微信开发者工具模拟器一切正常,扫码真机预览后列表加载失败,Network 显示net::ERR_CONNECTION_TIMED_OUT。
原因:真机上localhost指向手机自己,不是开发机;此外电脑防火墙也可能拦截局域网请求。
解决:baseUrl 改为开发机局域网 IP;在 Windows 防火墙入站规则里放行 IDEA 或 Tomcat 使用的端口。手机和电脑连同一个 Wi-Fi,确认手机能 ping 通电脑 IP。如果公司或校园网开了 AP 隔离,手机和电脑虽然在同一个 SSID 下却不在同一网段,临时开热点就能避开。
6. 进阶:动态标题、手机号授权,以及上线前的复现验证
小程序端有两个需求最容易在毕设答辩里被追问:一个是不同业务状态下页面标题要变,另一个是登录能不能拿到微信手机号。前者用wx.setNavigationBarTitle,后者要加一个button属性open-type="getPhoneNumber"。
// 页面 onShow 里根据业务状态动态设置标题 wx.setNavigationBarTitle({ title: role === 'repairer' ? '维修员工作台' : '我的维修' });这里的role从小程序本地存储读取,登录时后端返回当前用户身份。注意微信顶部导航栏固定高度是 44px,深色状态栏适配还要额外处理,开了自定义导航栏之后,所有页面的安全区都要重新计算,这是“顶部导航栏高度”相关搜索背后的真坑。
手机号授权需要用户主动点击才能触发,不能静默获取:
<button open-type="getPhoneNumber" bindgetphonenumber="onGetPhoneNumber">微信手机号快捷登录</button>拿到detail.code后交给后端,由后端调用微信接口换取手机号。毕设里如果小程序主体没有认证,可以在开发阶段返回模拟手机号来替代,但前端结构要保持完整,避免答辩时临时接不回来。
上线前我最后一个动作是整套流程从零复现一遍:删库、重建、导入 SQL、启动后端、起管理后台、微信开发者工具导入小程序端,完整跑一遍从用户提交维修单到维修员处理再到评价的链路。这几步看着繁琐,但能暴露“换台电脑就部署失败”的隐患。从那以后,我每次拿到别人源码都是先跑复现流程再碰代码,改完业务还强制走一遍构建产物验证。希望帮到你。
本文还有配套的精品资源,点击获取