简介:这份资源是面向高校计算机相关专业学生与Java初学者的一套微信小程序跑腿系统毕业设计完整源码,采用Java后端加微信小程序前端的技术组合,配合MySQL数据库,适合用于毕业设计、课程设计或小程序全栈入门练手。系统划分管理员、校友、跑腿员三类角色,管理员负责个人中心、校友与跑腿员管理、校友动态、发布任务、任务订单、消息中心及系统管理,校友在小程序端注册登录并发布跑腿任务,跑腿员则接单完成配送,业务闭环清晰,便于理解权限划分与订单流转逻辑。压缩包共1122个文件,约16.52MB,包含103个java后端源码、122个vue页面、151个js脚本、70个wxml与72个wxss小程序页面样式,以及2个sql数据库脚本和若干json、xml配置,前后端与数据库文件齐全。资源已有95人学习,可帮助读者快速搭建可运行项目、梳理表结构与接口设计,并在此基础上完成功能扩展与论文撰写。
1. 跑腿小程序源码拆解:从登录鉴权到订单调度的最小闭环
打开一份「微信小程序跑腿源码(java+小程序+mysql+LW)」的压缩包,多数人第一反应是找 README,结果发现只有一堆目录。这个标题背后其实是一套典型的校园/社区跑腿系统:用户端小程序下单,骑手端接单,Java 后端做订单调度与状态流转,MySQL 存业务数据,LW 通常是论文文档。它解决的是「帮买、帮送、帮取」这类短链路任务的信息撮合问题,适合做毕业设计、课程设计,或者作为接私活时快速搭原型的底子。
我见过太多人拿到源码后卡在第一步:微信开发者工具打开报错、后端连不上数据库、登录拿不到手机号。这篇笔记不逐行讲代码,而是按「环境跑通 → 登录鉴权 → 订单状态机 → 避坑 → 进阶」的顺序,把一份跑腿源码从能跑到能改的关键路径拆开。如果你手上有这份 zip,或者正准备自己写一套,下面的步骤和参数可以直接对照着调。
2. 把源码跑起来:环境、数据库与小程序配置
2.1 后端工程结构与依赖确认
拿到源码先别急着导入 IDE,用命令行扫一遍目录结构。典型的 Java 后端会分 controller、service、mapper、entity 几层,配合 pom.xml 或 build.gradle。先确认 JDK 版本,跑腿类项目多数用 JDK 8 或 11,Spring Boot 2.x 居多。
# 查看项目根目录结构,确认构建方式 ls -la # 如果有 pom.xml,查看 Spring Boot 版本和 Java 版本 grep -E "spring-boot|java.version" pom.xml逻辑说明:这一步是为了确认项目用的是 Maven 还是 Gradle,以及 Spring Boot 大版本。参数上重点看<java.version>和<parent>里的 spring-boot-starter-parent 版本。如果源码里写的是 JDK 1.8,你本地用 JDK 17 跑,大概率会在编译期报Unsupported class file major version,这时候要么装 JDK 8,要么在 pom 里升版本,但升版本可能引发依赖冲突,新手建议直接对齐源码声明的版本。
2.2 MySQL 建库与配置修改
跑腿系统的表通常包括用户表、骑手表、订单表、地址表、评价表。源码里一般会带一个.sql文件,导入之前先建库。
-- 建库,字符集用 utf8mb4 支持 emoji CREATE DATABASE errand_db DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; -- 导入源码自带的 sql 文件 -- 命令行方式:mysql -u root -p errand_db < errand_db.sql导入完成后,去application.yml或application.properties改数据库连接。常见配置项:spring.datasource.url、username、password、driver-class-name。MySQL 8.0 的驱动类是com.mysql.cj.jdbc.Driver,5.7 可以用com.mysql.jdbc.Driver,写错会报Loading class ... is deprecated或直接连不上。url 里记得加serverTimezone=Asia/Shanghai,否则时间字段可能差 8 小时,订单创建时间对不上,后面排查状态流转时会很痛苦。
2.3 小程序端 appid 与请求域名配置
小程序端用微信开发者工具打开,先改project.config.json里的appid。没有自己的 appid 可以用测试号,但测试号不支持某些高级接口。然后在app.js或请求封装文件里找baseUrl,改成你后端实际运行的地址。
// utils/request.js 里通常有类似配置 const BASE_URL = 'http://localhost:8080/api'; // 微信开发者工具里勾选「不校验合法域名」才能用 localhost逻辑说明:微信小程序正式环境要求 https 且域名备案,但开发阶段可以在开发者工具「详情 → 本地设置」里勾选「不校验合法域名、web-view(业务域名)、TLS 版本以及 HTTPS 证书」,这样 localhost 和 http 都能跑。参数上注意端口要和后端server.port一致,路径前缀/api要和 controller 的@RequestMapping对上,否则全是 404。
3. 登录与手机号获取:跑腿系统的身份入口
3.1 微信登录 code 换 openid 的完整链路
跑腿系统里用户和骑手是两类角色,但登录入口通常共用一个微信授权。流程是:小程序调wx.login拿 code,把 code 发给后端,后端用 code + appid + secret 调微信接口换 openid 和 session_key。
// 小程序端:获取 code 并发送给后端 wx.login({ success: (res) => { if (res.code) { wx.request({ url: BASE_URL + '/auth/login', method: 'POST', data: { code: res.code }, success: (resp) => { // resp.data 里应包含 token 和角色信息 wx.setStorageSync('token', resp.data.token); } }); } } });逻辑说明:code 只能用一次,五分钟过期。后端拿到 code 后请求https://api.weixin.qq.com/sns/jscode2session,参数是appid、secret、js_code、grant_type=authorization_code。返回的 openid 是用户唯一标识,session_key 用于解密手机号。这里的关键参数是 appid 和 secret,必须和project.config.json里的一致,否则报invalid appid。token 建议用 JWT,存 openid 和角色,后续接口用拦截器校验。
3.2 获取手机号的两种方式与解密逻辑
热词里「微信小程序登录获取手机号」是高频问题。目前常见两种:一是button组件的open-type="getPhoneNumber",用户点击后拿到加密的encryptedData和iv;二是新版getPhoneNumber接口直接返回 code,后端换手机号。
// 后端解密手机号(旧版 encryptedData 方式) // 依赖:commons-codec、bcprov 等 String result = AESUtil.decrypt(encryptedData, sessionKey, iv); // result 是 JSON,包含 phoneNumber、purePhoneNumber 等字段逻辑说明:解密用 AES-128-CBC,sessionKey 来自登录时微信返回,iv 来自前端。参数上注意 sessionKey 必须和当前用户对应,如果用户重新登录,旧 sessionKey 失效,解密会报pad block corrupted。新版接口更简单:前端getPhoneNumber返回 code,后端调phonenumber.getPhoneNumber接口,用 access_token 换手机号。access_token 需要缓存,两小时过期,频繁刷新会触发频率限制。
3.3 角色区分与 token 拦截器配置
跑腿系统里用户和骑手登录后看到的界面不同。常见做法是在用户表加role字段,登录时返回角色,小程序根据角色跳不同 tab。后端用 Spring 拦截器或 Spring Security 校验 token。
// 拦截器里校验 token 并放行白名单 public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { String token = request.getHeader("Authorization"); if (token == null || !jwtUtil.validate(token)) { response.setStatus(401); return false; } return true; }逻辑说明:白名单要放行/auth/login、/auth/phone等登录相关接口,否则死循环。参数上 JWT 的过期时间建议设 7 天,跑腿场景用户不会频繁登录。角色校验可以在拦截器里根据路径判断,比如/rider/**只允许骑手角色访问,返回 403。这里容易翻车的是 token 放在 header 还是 query,小程序端要统一,建议放Authorizationheader。
4. 订单状态机:跑腿系统的核心调度逻辑
4.1 订单表设计与状态字段取值
订单表是跑腿系统的核心。典型字段:订单号、用户 id、骑手 id、类型(帮买/帮送/帮取)、起点、终点、金额、状态、创建时间、接单时间、完成时间。状态字段用整数或枚举,常见取值:0 待接单、1 已接单、2 配送中、3 已完成、4 已取消。
CREATE TABLE `order` ( `id` bigint NOT NULL AUTO_INCREMENT, `order_no` varchar(32) NOT NULL, `user_id` bigint NOT NULL, `rider_id` bigint DEFAULT NULL, `type` tinyint NOT NULL COMMENT '1帮买 2帮送 3帮取', `status` tinyint NOT NULL DEFAULT '0' COMMENT '0待接单 1已接单 2配送中 3已完成 4已取消', `amount` decimal(10,2) DEFAULT NULL, `create_time` datetime DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `uk_order_no` (`order_no`), KEY `idx_status` (`status`) );逻辑说明:status加索引是因为骑手端要频繁查询待接单列表。order_no唯一索引防止重复提交。金额用 decimal 不用 float,避免精度问题。参数上type和status用 tinyint 省空间,但要在代码里定义枚举对应,否则后期维护看不懂数字含义。
4.2 骑手接单的并发控制与乐观锁
多个骑手同时抢一单是跑腿系统的经典并发场景。如果直接update order set rider_id=? where id=?,可能两个骑手都以为自己接单成功。常见做法是用乐观锁:更新时带上 status 条件。
UPDATE `order` SET rider_id = #{riderId}, status = 1, accept_time = NOW() WHERE id = #{orderId} AND status = 0;逻辑说明:这条 SQL 返回影响行数,如果为 0 说明订单已被抢或状态不对,后端返回「手慢了」。参数上status = 0是前提条件,确保只有待接单状态才能被接。更严谨的做法是加版本号字段version,每次更新version = version + 1,但跑腿场景用 status 条件已经够用。注意事务隔离级别,MySQL 默认 RR 下这条 update 会加行锁,并发时后到的会等待,不会超卖。
4.3 订单状态流转的接口与校验
状态流转要严格按 0→1→2→3 走,不能跳步。每个流转接口都要校验当前状态和操作人身份。
// 骑手点击「开始配送」 public void startDelivery(Long orderId, Long riderId) { Order order = orderMapper.selectById(orderId); if (order.getStatus() != 1) { throw new BizException("订单状态不允许开始配送"); } if (!order.getRiderId().equals(riderId)) { throw new BizException("无权操作此订单"); } order.setStatus(2); orderMapper.updateById(order); }逻辑说明:先查再判断再更新,三步缺一不可。参数上riderId从 token 里取,不要从前端传,否则可以伪造。状态判断用!=而不是>,因为取消状态 4 是特殊分支。这里容易踩的坑是并发下查和更新之间状态被改,可以用update ... where status = 1的方式保证原子性,和接单逻辑一致。
5. 跑腿源码避坑:五个高频翻车现场
5.1 小程序请求报「不在以下 request 合法域名列表中」
现象:开发者工具里请求后端接口,控制台报域名不合法,接口全部失败。原因:微信小程序默认校验请求域名,localhost 和 http 都不在白名单。解决:开发者工具「详情 → 本地设置」勾选「不校验合法域名」,或者把后端部署到 https 域名并配置到小程序后台。注意正式发布必须用 https,开发阶段勾选即可。
5.2 数据库连接报「Public Key Retrieval is not allowed」
现象:MySQL 8.0 下启动后端,报Public Key Retrieval is not allowed。原因:MySQL 8.0 默认认证插件是 caching_sha2_password,JDBC 连接需要允许公钥检索。解决:在 url 后加allowPublicKeyRetrieval=true&useSSL=false,或者把用户认证插件改成 mysql_native_password。参数上useSSL=false在开发环境可以,生产建议开 SSL。
5.3 手机号解密报「pad block corrupted」
现象:用户授权手机号后,后端解密失败,报pad block corrupted或invalid iv。原因:sessionKey 过期或与当前用户不匹配,或者前端传的 iv 被 URL 编码过。解决:确保 sessionKey 是最近一次登录返回的,iv 和 encryptedData 原样传输不要编码。如果用户长时间未操作,重新调wx.login刷新 sessionKey。新版 code 换手机号接口没有这个问题,建议优先用新版。
5.4 订单列表时间显示差 8 小时
现象:订单创建时间是 14:00,数据库里存的是 06:00,或者小程序显示时间不对。原因:JDBC url 没配时区,或者 MySQL 服务端时区是 UTC。解决:url 加serverTimezone=Asia/Shanghai,MySQL 配置文件里设default-time-zone='+08:00'。参数上注意datetime和timestamp的区别,timestamp 会随时区转换,datetime 不会,跑腿系统建议用 datetime 存业务时间。
5.5 骑手接单后用户端看不到状态更新
现象:骑手接单成功,但用户端订单状态还是「待接单」。原因:用户端没有轮询或 WebSocket 推送,或者查询接口缓存了旧数据。解决:简单做法是用户端下拉刷新或定时轮询,间隔 5-10 秒;进阶做法用 WebSocket 推送状态变更。参数上轮询间隔不要太短,否则服务器压力大,跑腿场景 5 秒足够。检查接口是否走了缓存,MyBatis 一级缓存是 session 级别,一般不影响,二级缓存要确认是否开启。
6. 从能跑到能改:跑腿源码的二次开发切入点
把源码跑通只是第一步,真正有价值的是知道往哪里改。我一般会先看订单状态机,这是跑腿系统的骨架,改这里能衍生出很多功能。比如加一个「骑手转单」:在状态 1 和 2 之间插入转单逻辑,原骑手发起转单,订单回到待接单池但标记转单来源。实现上在订单表加transfer_from字段,转单时更新 rider_id 为空、status 回 0,同时记录原骑手。
第二个切入点是计价规则。源码里金额可能是写死的或简单按距离算,实际跑腿场景要按重量、距离、时段动态计价。可以抽一个PriceService,入参是起点终点经纬度、物品重量、下单时间,出参是金额。距离用高德或腾讯地图的骑行路径规划接口算,注意小程序端要配置对应的 key 和域名白名单。
第三个是消息通知。跑腿系统里订单状态变更要通知对方,小程序订阅消息是标配。在wx.requestSubscribeMessage里让用户授权,后端在状态变更时调subscribeMessage.send接口。参数上模板 id 要在小程序后台申请,data里的字段要和模板对应,否则报data format error。订阅消息是一次性的,用户授权一次只能发一条,所以要在关键节点让用户重新授权。
验证改动是否生效,我习惯用 Postman 或 curl 直接打后端接口,绕过小程序端,先确认后端逻辑对,再联调前端。比如测接单并发,用ab或wrk压测接单接口,看是否只有一个请求返回成功。数据库层面开 general_log 看实际执行的 SQL,确认乐观锁条件生效。
最后说个血泪经验:改源码前先 git init 提交一版原始代码,每改一个功能提交一次。跑腿系统涉及用户、骑手、订单三方,改一处很容易影响另一处,有后悔药可吃。数据库改表结构前先 mysqldump 备份,别问我怎么知道的。希望帮到你。
本文还有配套的精品资源,点击获取