资讯详情 微信小程序上门维修系统毕业设计:从环境搭建到业务逻辑解析
📅 2026/10/9 3:04:34
简介这是一份面向微信小程序毕业设计的完整源码包实现上门维修系统的用户、维修员、管理员三大业务模块。用户端支持首页浏览、广告资讯查看以及个人中心下的维修信息、维修记录、评价信息、我的收藏等管理维修员端可处理维修信息、记录与评价管理员端则覆盖用户管理、维修员管理、维修信息管理、维修记录管理、评价信息管理、广告信息管理和系统管理等完整后台功能适合计算机相关专业学生用于课程设计、毕业设计或项目实训。资源共1249个文件除Java源码、Vue前端页面和微信小程序wxml/wxss页面外还包含大量png图片、js脚本、svg图标、json配置等辅助资源以及数据库SQL文件压缩包整体26.02MB代码结构清晰、前后端分离、可直接导入开发环境运行。项目附带详细环境说明包括JDK1.8、MySQL5.7、Maven3.3、Tomcat7、Navicat11及微信开发者工具等方便对照搭建。目前已有87人学习下载是一份上手门槛低、逻辑完整、适合参考与二次开发的毕业设计资源。1. 为什么毕业设计选“上门维修系统”比选商城更划算每年毕业季都能看到大量“XX商城”“XX管理系统”扎堆出现答辩现场十个里有八个是重复选题。如果你现在手里拿的是这份【微信小程序毕业设计】上门维修系统源码java小程序mysqlLW那你其实选了一条更实用的路预约维修这种带订单流转、状态机、角色权限、消息触达的真实场景比单纯堆CRUD的商城系统更容易讲出业务深度也更容易让评委问不出“你这系统到底解决了什么问题”。这套系统的典型组合是微信小程序做用户端下单与查看进度JavaSpring Boot 或 SSM具体看包里代码结构做后端接口MySQL 存订单、用户、师傅、评价这些核心数据外加一份 LW论文/文档。它面向的是“家里水管坏了、电器不转了附近找个师傅上门修”这种低频但刚需的场景。适合打算用现成骨架快速跑通、再往里面加自己思路的在校生也适合想接私活或做产品原型的开发者。能解决什么问题一句话把“打电话找人修”变成“小程序下单、系统派单、师傅接单、用户评价”的标准化流程。下面直接从跑通它开始每一章都给你能照做的步骤。2. 先搞懂这套系统的骨架技术栈选型与数据流2.1 为什么是 Java 小程序 MySQL而不是其他组合市面上毕业设计常见的组合有 PHP 版、Python 版、.NET 版但这套选择 Java 是有理由的。Spring Boot 生态对新手最友好的地方在于“约定大于配置”一个application.yml配好数据源RestController写接口MyBatis 或 MyBatis-Plus 操作数据库几乎不需要写一行 Spring XML 配置。对毕业设计来说这意味着你把项目导入 IDEA 后能最快速度看到接口跑起来而不是先把 SSH 整合折腾两周。MySQL 在这个体量下是合理选择。上门维修系统的核心数据——用户表、师傅表、订单表、服务类目表——加起来也就四五张表数据量在演示场景下千条级别MySQL 5.7 或 8.0 都毫无压力。而且 MySQL 的安装、可视化工具Navicat、DBeaver都比 PostgreSQL 更普及你答辩前在演示机器上临时装环境也更快。小程序端选原生框架而不是 uni-app好处是调试简单。微信开发者工具打开项目就能跑不用先搭一遍 Node 和 HBuilderX 的链子。许多同学踩过 uni-app 打包的坑——原生小程序编译不过、npm 依赖版本冲突——这些在这个项目里都不存在。当然代价是代码只跑微信端但这正好符合毕业设计的范围控制。2.2 系统角色与核心数据流用户、师傅、管理员三方怎么协作整套系统不是简单的“用户下单-师傅接单”两方模型带管理员的话是三端。用户端小程序里做的事注册登录、浏览维修类目、提交预约单、查看订单状态、对完成的订单评价。师傅端可能是小程序或后台网页取决于源码包里的前端工程数量做的事接收派单提醒、确认接单、更新维修进度、申请完成订单。管理员端通常在 Java 后端附带的管理页面做的事审核师傅入驻、手动派单、处理纠纷订单、查看统计报表。这三方落到数据库层面就是三张核心表外加订单表。订单表是整个系统的主动脉状态字段从“待派单”到“已接单”“维修中”“待支付”“已完成”“已取消”流转。理解这个状态机是后续改业务逻辑的钥匙。-- 订单表的核心字段设计各版本源码可能略有差异但思路一致 CREATE TABLE repair_order ( id bigint(20) NOT NULL AUTO_INCREMENT, order_no varchar(32) NOT NULL COMMENT 订单编号形如 WX20240512xxxx, user_id bigint(20) NOT NULL COMMENT 下单用户ID, worker_id bigint(20) DEFAULT NULL COMMENT 接单师傅ID未派单时为空, category_id bigint(20) NOT NULL COMMENT 维修类目如水管、电路、家电, status tinyint(4) NOT NULL DEFAULT 0 COMMENT 状态0待派单 1已接单 2维修中 3待支付 4已完成 5已取消, address varchar(255) NOT NULL COMMENT 上门地址, appointment_time datetime DEFAULT NULL COMMENT 预约上门时间, description text COMMENT 故障描述, create_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id), KEY idx_user_id (user_id), KEY idx_worker_id (worker_id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT维修订单表;这里有几个字段值得注意。order_no不用自增 ID 直接暴露给用户是为了防止别人通过遍历订单号看到无关订单——这是演示系统最容易被追问的点。status用 tinyint 而不是字符串是为了查询和索引效率但代价是代码里要维护状态枚举新手容易在这里漏掉状态流转判断。appointment_time允许为空因为有些用户下单时不确定时间选了“尽快上门”。2.3 表结构还有哪些用户表、师傅表、评价表的边界用户和师傅其实是两类不同角色但很多简化版系统会把它们塞进一张 user 表加个 role 字段。这套源码如果是正经设计应该是拆开的。拆开的好处是师傅有独立的审核状态、服务类目、接单数量统计塞一起会把这些字段污染到用户表里。你拿到代码后先看一眼表结构如果是合并的也没关系跑通后再拆也行。评价表关联的是订单表而不是用户表这是一个容易被忽略的设计。一个订单只能评价一次所以评价表里order_id应该加唯一索引否则用户反复提交会产生多条评价统计师傅评分时会算错。这个细节体现的是对业务的理解答辩时能主动讲出来比背十个八股文都管用。3. 从压缩包到跑起来环境准备与最小启动步骤3.1 环境清单JDK、MySQL、微信开发者工具缺一不可开工前先把工具链备齐。JDK 建议 1.8 或 8u 系列别一上来装 JDK 17——很多老项目的 pom.xml 里依赖没跟上可能会出现一些兼容性报错哪怕能跑也会因为你改了 pom 而引入新问题。MySQL 用 5.7 最稳8.0 也兼容但如果你用的是 8.0 要注意连接驱动和useSSLfalse的参数。微信开发者工具用稳定版即可不用追最新的 RC 版。还有一个容易被忽略的是 Lombok 插件。如果源码里用了Data注解你的 IDEA 必须装 Lombok 插件并且在Settings Build Compiler Annotation Processors里勾选 Enable annotation processing否则项目一启动就报“找不到符号 getXxx()”。这个坑每年能绊倒一半的人先写在这里。3.2 数据库初始化用 .sql 文件建表而不是手工敲 SQL源码包里通常会带一个repair.sql或db.sql这是整套系统的地基。别用 Navicat 打开 SQL 文件直接执行我建议用命令行方式这样报错信息最直接也方便录演示视频时展示操作过程。# 登录 MySQLroot 密码换成你自己的 mysql -uroot -p # 创建数据库注意字符集要跟小程序端传参对齐 CREATE DATABASE repair_system DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; # 退出后用重定向导入 SQL 文件Windows 下路径用反斜杠或直接拖文件进终端 mysql -uroot -p repair_system /path/to/repair.sql # 验证导入结果 mysql -uroot -p -e USE repair_system; SHOW TABLES;导入成功后你应该能看到用户表、师傅表、订单表、评价表、管理员表等。如果SHOW TABLES什么都看不到先检查 SQL 文件开头有没有CREATE DATABASE语句——如果有直接导入会冲突需要把文件开头的建库语句删掉再执行。这一步不检查后面所有接口都会报“Table doesnt exist”。关于字符集多说一句用utf8mb4而不是utf8是因为用户在小程序端可能输入 Emoji 表情utf8存不进去会报错。虽然正常提交故障描述不太会带表情但地址栏里偶尔会有特殊字符用 utf8mb4 一劳永逸。3.3 后端启动改三个配置就能跑后端工程导入 IDEA 后先别急着点运行改三个地方。第一是数据库连接在application.yml或application.properties里把 URL、用户名、密码改成你自己本机的。第二是端口Spring Boot 默认 8080如果被占用就改成 8081但记得小程序端请求地址也要一起改。第三是微信小程序登录相关的 appid 和 secret——没有真实小程序账号时可以先填测试值把微信登录逻辑跳过用 Mock 登录。# application.yml 关键配置段 server: port: 8080 spring: datasource: url: jdbc:mysql://localhost:3306/repair_system?useUnicodetruecharacterEncodingutf8useSSLfalseserverTimezoneAsia/Shanghai username: root password: 123456 driver-class-name: com.mysql.jdbc.Driver # 微信小程序配置没有正式账号时用测试号 wx: appid: your-test-appid secret: your-test-secretserverTimezoneAsia/Shanghai这个参数必须加否则 MySQL 8.0 连接时会报时区错误。useSSLfalse是防止本机 MySQL 没配 SSL 证书时报警告。driver-class-name要注意版本——如果是 MySQL 8.0 要用com.mysql.cj.jdbc.Driver5.7 用com.mysql.jdbc.Driver写错了启动就直接失败。这些都改完后直接运行主类通常是Application或RepairApplication。看到“Started Application in X seconds”就说明后端起来了。为了验证接口真的能用打开浏览器访问http://localhost:8080/如果返回 JSON 串而不是报错页说明 Spring Boot 部署成功。3.4 小程序端配置打开项目、改接口地址、跑通首页小程序端打开微信开发者工具选择“导入项目”把你解压出来的小程序目录一般是miniapp或repair-miniapp选中AppID 填测试号点击“测试号”即可不需要自己注册。这一步很多人卡住主要是目录选错了——要选包含app.json的那个文件夹不是外层打包目录。小程序端最重要的修改是接口地址。开发者工具默认请求http://localhost:8080但微信小程序的网络请求对域名有校验本地调试要在“详情-本地设置”里勾选“不校验合法域名”。不勾选的话所有请求都会报url not in domain list。// config.js 里统一管理接口地址改这一处即可 module.exports { baseUrl: http://localhost:8080, // 图片上传接口海报/故障照片都走这里 uploadUrl: http://localhost:8080/api/upload }// 首页加载维修类目的请求示例 wx.request({ url: config.baseUrl /api/category/list, method: GET, success(res) { // res.data 里是类目列表渲染到页面 console.log(类目加载成功, res.data); }, fail(err) { wx.showToast({ title: 网络异常请检查后端是否启动, icon: none }); } })后端启动的前提下首页能显示出维修类目列表就说明前后端链路打通了。到这一步你已经完成了从压缩包到“能演示”的第一阶段。如果你的目标是先把系统跑起来录个视频可以直接跳到第五章看避坑如果打算认真改代码继续往下看业务逻辑怎么和接口对应。4. 核心业务代码怎么读从下单到完成的完整链路4.1 小程序登录与手机号授权最容易改出问题的环节微信小程序的登录逻辑跟传统账号密码完全不同。常规做法是wx.login()拿到临时 code发给后端后端用 code 换 openid再拿 openid 去数据库找用户。新版的手机号授权需要用户主动点击按钮触发getPhoneNumber拿到动态令牌再换手机号而不是直接返回明文。这套源码里大概率已经封装好了这两个接口。你需要关注的是后端WxLoginController里的处理逻辑PostMapping(/wx/login) public Result login(RequestBody LoginRequest request) { // 1. 调用微信接口用 code 换 openid String openid wxService.getOpenid(request.getCode()); // 2. 根据 openid 查用户表 User user userMapper.selectByOpenid(openid); // 3. 查不到就自动注册新用户 if (user null) { user new User(); user.setOpenid(openid); user.setNickname(微信用户); user.setAvatar(default.png); userMapper.insert(user); } // 4. 生成登录态 token 返回给小程序端 String token JwtUtil.createToken(user.getId(), user.getOpenid()); return Result.success(token); }这段代码里最值得关注的是“查不到就自动注册”这个设计。很多系统让用户手动填注册表单但小程序场景里用户没有耐心输入一键登录才是常态。token 用的是 JWT好处是后端不必存 session接口直接验签就能识别用户。你改成其他登录方式没问题但要知道 token 里不要放敏感信息因为 JWT 的 payload 只是 Base64 编码明文可读。手机号授权是另一条链路通常是在登录之后用户主动点击“绑定手机号”按钮时才触发。这块的主要坑是getPhoneNumber拿到的code只能调用一次微信接口而且五分钟内有效不能提前调用也不能连续调用。如果源码里把这部分写成了直接返回手机号说明用的是旧版接口换到新版会报invalid code。4.2 预约下单小程序表单如何组装成订单请求下单页面是用户看到的第一个业务页面一般长这样选择维修类目 → 填写故障描述 → 选择预约时间 → 填写上门地址 → 提交订单。前端收集完这些信息后组装成 JSON 发给后端。// 小程序端提交预约订单 submitOrder() { const formData { categoryId: this.data.selectedCategory.id, description: this.data.description.trim(), appointmentTime: this.data.appointmentTime, // 格式YYYY-MM-DD HH:mm:ss address: this.data.address, contactName: this.data.contactName, contactPhone: this.data.contactPhone }; wx.request({ url: config.baseUrl /api/order/create, method: POST, data: formData, header: { Authorization: Bearer ${wx.getStorageSync(token)} }, success(res) { if (res.data.code 200) { wx.redirectTo({ url: /pages/order/detail?id${res.data.data.id} }); } else { wx.showToast({ title: res.data.msg || 下单失败, icon: none }); } } }); }注意header里的 Authorization 字段这是后端识别用户身份的关键。如果请求不带 token后端拦截器会直接返回 401。新手经常犯的错是把 token 写死在代码里或者从 storage 里取的时候 key 拼错——这里是wx.getStorageSync(token)跟登录成功时wx.setStorageSync(token, res.data.data.token)的 key 必须完全一致。后端接收订单的接口要校验的东西比较多类目是否存在、地址是否为空、手机号格式是否正确。源码里如果这些校验不完整建议你自己补上因为答辩时评委很可能问“如果用户提交空地址会怎样”。最简单的做法是用 Spring 的Validated注解加NotBlank但老项目里通常是在代码里手动判断if (StringUtils.isBlank(order.getAddress())) { return Result.error(400, 地址不能为空); } if (!RegexUtil.isMobile(order.getContactPhone())) { return Result.error(400, 手机号格式不正确); }下单完成后后端把订单状态置为0待派单接下来就是管理员端的工作了。4.3 派单与接单订单状态如何流转谁负责推进这是整套系统业务逻辑的核心也是最值得在论文里画图讲清楚的部分。订单创建后状态为待派单管理员看到新订单后手动指派师傅也有自动派单版本——按距离或按接单量最少优先。师傅端看到派给自己的单后点“接单”状态变为已接单上门维修完成后点“完成服务”状态变为待支付用户支付或点击确认后状态变为已完成。// 状态流转的核心逻辑各版本命名可能不同 public Result updateStatus(Long orderId, Integer targetStatus, Long operatorId) { RepairOrder order orderMapper.selectById(orderId); // 从待派单到已接单必须是该订单指派的师傅才能操作 if (targetStatus 1) { if (!order.getWorkerId().equals(operatorId)) { return Result.error(403, 非接单师傅无权操作); } } // 从已接单到维修中师傅操作 // 从维修中到待支付师傅操作说明维修已完成 // 从待支付到已完成用户操作确认 if (!StatusFlow.canTransfer(order.getStatus(), targetStatus)) { return Result.error(400, 非法状态流转); } order.setStatus(targetStatus); orderMapper.updateById(order); return Result.success(); }这段代码虽然简单但蕴含了两个关键设计。第一个是操作者校验不是登录用户就能随便改状态师傅只能改自己接的单用户只能改自己的单。第二个是状态机流转校验不能让用户把待派单直接改成已完成必须一层层走。源码里如果用的是栅栏数组或者 if-else 判断状态分支读起来会复杂一些但思路都是一样的。这块是你改代码时最容易加功能的地方。比如加一个“取消订单”的入口用户只能在待派单状态下取消师傅接单后需要申请管理员同意才能取消。又比如加一个“超时自动取消”下单后 30 分钟没派单系统自动把订单置为已取消。这两种做法都能直接体现你对业务的理解而且不需要大改表结构加个定时任务或者判断条件就行。4.4 评价接口为什么评价要绑订单而不是绑用户订单完成后用户可以对师傅进行评价。这个接口的表结构设计透露着一线经验——评价表里的order_id是有唯一索引的而不是靠用户 ID。CREATE TABLE worker_evaluation ( id bigint(20) NOT NULL AUTO_INCREMENT, order_id bigint(20) NOT NULL COMMENT 关联订单ID, user_id bigint(20) NOT NULL COMMENT 评价人, worker_id bigint(20) NOT NULL COMMENT 被评价师傅, rating tinyint(4) NOT NULL DEFAULT 5 COMMENT 评分1-5, content varchar(500) DEFAULT NULL COMMENT 评价内容, create_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id), UNIQUE KEY uk_order_id (order_id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT师傅评价表;uk_order_id这个唯一索引就是面试官最爱问的“一个订单能评价几次”的答案。如果不加这个索引用户手滑多点两次提交就会生成多条评价师傅的评分会被刷低。另外一个细节是rating用 tinyint 而不是 int节省存储空间而且业务上也不可能出现 10 分制——这个判断来自对业务的熟悉不是背规范背出来的。加了唯一索引之后代码里还要处理重复评价的异常。不能依赖数据库报错让用户看到 500要提前查一次Evaluation existing evaluationMapper.selectByOrderId(orderId); if (existing ! null) { return Result.error(400, 该订单已评价不能重复提交); }这叫作“先查后写”虽然会多一次查询但用户体验远比直接让数据库抛 DuplicateKeyException 强。4.5 全局拦截器与权限控制哪些接口需要登录才能访问小程序端的每个请求都带 token但后端不可能在每个接口里都写一遍 token 校验。常规做法是写一个拦截器在请求进 Controller 之前统一处理。Component public class AuthInterceptor implements HandlerInterceptor { Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // 放行登录和注册接口 String uri request.getRequestURI(); if (uri.contains(/wx/login) || uri.contains(/wx/register)) { return true; } // 其他接口必须校验 token String token request.getHeader(Authorization); if (StringUtils.isBlank(token) || !JwtUtil.verify(token)) { response.setStatus(401); response.setContentType(application/json;charsetUTF-8); response.getWriter().write({\code\:401,\msg\:\未登录或登录已过期\}); return false; } return true; } }这段代码里有几个处理细节值得注意。token 为空或者验签失败时返回 401 而不是 200 再包一层业务错误码这是符合 HTTP 语义的写法前端在fail回调里统一处理跳转登录页即可。放行接口要精确控制除了登录注册外通常还要放行图片上传、公告列表这类不需要登录的接口。放行做太宽会导致未登录也能查订单做太窄会让登录接口本身被拦截形成死循环。你在跑通项目后可以做一个简单的验证实验把浏览器里带的 Authorization 删掉再请求订单列表接口看是否返回 401。如果返回的是 200 和数据说明拦截器配置有问题——要么是没注册到 WebMvcConfigurer要么是路径匹配错了。这个问题答辩时被问的概率很高提前自查一下。5. 常见问题排查与避坑五个让项目起不来的致命细节5.1 端口被占用导致后端启动失败现象启动 Spring Boot 时控制台报Port 8080 was already in use应用启动到一半就退出了。原因本机其他服务占了 8080 端口常见于之前启动过别的 Java 进程、Tomcat 实例甚至是某些开发工具的代理端口。解决改端口最快。在application.yml里把server.port改成 8081同时把小程序端config.js里的baseUrl同步改成http://localhost:8081。不要用命令行kill -9 PID去强杀进程因为你可能误杀别的服务。先执行netstat -ano | findstr 8080Windows或lsof -i:8080Mac/Linux查看占用进程确认是自己之前残留的 Java 进程再处理。5.2 MySQL 时区报错导致数据源初始化失败现象启动后端报The server time zone value Öйú±ê׼ʱ¼ä is unrecognized或者Could not create connection to database server。原因MySQL 8.0 的时区默认值在 JDBC 驱动下无法识别连接串里没有显式指定serverTimezone。解决在 JDBC URL 后面加上serverTimezoneAsia/Shanghai完整参数是jdbc:mysql://localhost:3306/repair_system?useUnicodetruecharacterEncodingutf8useSSLfalseserverTimezoneAsia/Shanghai。如果还报 SSL 告警把useSSLfalse也加上。改完配置必须重启应用只刷新配置文件不生效。5.3 小程序请求报“url not in domain list”或 500 状态码现象在微信开发者工具里请求接口控制台报下单失败或者显示网络错误。原因两个坑叠在一起。第一是开发者工具默认校验域名合法性本地 localhost 不在白名单里需要在“详情 - 本地设置 - 勾选不校验合法域名”。第二是如果基础库版本太新开发者工具对未配置域名请求会比较严格需要把“增强编译”关掉再试。解决本地调试阶段直接勾选“不校验合法域名、web-view业务域名、TLS 版本以及 HTTPS 证书”。如果你已经换成了真机预览这个选项不生效这时需要在小程序后台把本机局域网 IP 配置为 request 合法域名——但本地开发完全没有必要用开发者工具即可。真机调试只留到最后演示环节再用并且要保证手机和电脑在同一局域网。5.4 IDEA 编译报“找不到符号 getXxx()”Lombok 没生效现象项目一启动或编译时报大量找不到 getter/setter 方法指向的类上明明写着Data。原因Lombok 依赖已经加进 pom.xml但 IDEA 没装 Lombok 插件或者装了插件但没开启注解处理。IDEA 默认不处理 Lombok 生成的代码必须在设置里显式打开。解决打开Settings Plugins搜索 Lombok 并安装。然后去Settings Build, Execution, Deployment Compiler Annotation Processors勾选Enable annotation processing。两个设置都完成后重启 IDEA等 Maven 重新导入依赖再点击编译。如果用的是 Eclipse也需要在Maven Annotation Processing里勾选对应选项。5.5 前端下拉刷新和顶部导航栏错位iPhone 刘海屏适配现象小程序页面顶部内容被刘海遮挡或者页面往下拉时能看到白条背景。原因微信小程序默认导航栏只适配普通屏幕iPhone X 以上机型有刘海区域navigationStyle: custom模式下内容从屏幕最顶上开始布局没留安全区。这个问题在开发者工具里用 iPhone 6 模拟器看不出来但在真机上特别明显。解决要么不自定义导航栏用微信原生导航栏组件navigationBarTitleText设置标题让微信自己处理适配要么在自定义导航栏的页面里拿到状态栏高度后动态垫高// app.js 里获取全局信息 const sysInfo wx.getSystemInfoSync(); // 页面里使用paddingTop sysInfo.statusBarHeight Page({ data: { statusBarHeight: wx.getSystemInfoSync().statusBarHeight } })然后在 WXML 里给导航栏容器加上stylepadding-top: {{statusBarHeight}}px。这个适配经验虽然和业务逻辑无关但答辩演示时如果用的是 iPhone这个小细节会让系统观感专业很多。6. 答辩前验证与二开建议把毕业设计从“跑起来”做到“讲清楚”系统跑通只是及格线。评委问“这个系统的核心难点是什么”时你不能只说“我用了 Spring Boot 和 MyBatis”。拿出验证过的数据和能讲深的功能演进才是拿高分的底气。先做一轮完整的功能验收。建一个新用户账号走一遍“下单 → 管理员派单 → 师傅接单 → 完成服务 → 用户评价”的完整链路每个步骤截图保存。截图不要随手拍按时间顺序整理到答辩 PPT 里配合文字标注当前状态。这比放一堆代码截图有说服力得多评委能看到你真的操作过系统而不是只跑了个首页。然后挑一个模块做功能性增强。最容易出效果的是“自动派单”逻辑。原系统如果只有手动派单你写一个简单的轮询或定时任务空闲师傅中按当前未完成订单数最少排序自动指派给师傅。用 Quartz 或 Spring 自带的Scheduled都能实现代码量不大但业务价值明显答辩时可以讲“我采用了负载最低优先策略而不是随机派单提高了响应效率”。配合订单表里加一个assign_time字段就能讲清楚排班思路。另一个值得做的是数据统计可视化。用 ECharts 或小程序原生 canvas 画一个管理员端的工作量统计页面师傅本月完成订单数、维修类目占比、用户评分分布。数据从订单表里GROUP BY聚合出来SQL 语句就两三行但视觉冲击力远超纯表格。-- 师傅本月完成订单数统计以 MySQL 为例 SELECT w.id, w.name, COUNT(o.id) AS order_count FROM worker w LEFT JOIN repair_order o ON o.worker_id w.id AND o.status 4 AND o.update_time DATE_FORMAT(CURDATE(), %Y-%m-01) GROUP BY w.id, w.name ORDER BY order_count DESC;这段 SQL 里LEFT JOIN而不是INNER JOIN是为了把没接单的师傅也统计进来订单数为 0否则列表会漏人。status 4是已完成状态如果你的表结构里状态定义不一样先执行SELECT * FROM repair_order LIMIT 1;看看真实数值不要想当然。DATE_FORMAT(CURDATE(), %Y-%m-01)是当月第一天统计口径是自然月如果你导师想看最近 30 天改成DATE_SUB(CURDATE(), INTERVAL 30 DAY)即可。代码层面最后提一个建议给项目补上README.md。包括环境要求JDK 版本、MySQL 版本、Node 版本、部署步骤建库、导数据、改配置、启动、测试账号管理员、师傅、用户三种角色的登录方式。这份文档可以放进论文附录也可以给导师或评审老师直接看。别觉得浪费时间——一个能按文档零基础部署的项目和你含糊一句“环境有点问题”的项目专业度差异一眼就看得出来。最后说一下我自己的血泪教训毕业设计答辩前一天我把小程序端一个请求地址从 localhost 改成了局域网 IP想着用手机投屏演示更真实。结果 IP 写错一位所有接口全挂。折腾了半小时才发现是这种低级错误。后来我养成一个习惯任何改动都先在模拟器里完整走一遍核心流程再考虑花活。系统的稳定演示永远比花哨功能更得分。这次的方案里核心流程能跑通、状态流转能讲清、SQL 能写对、额外功能能自选其一你已经超过周围大半同学了。照着上面的步骤做不慌希望帮到你。本文还有配套的精品资源点击获取