简介:同城上门家政按摩H5小程序源码是一套面向O2O上门服务场景的前端工程,面向正在搭建家政、按摩等预约平台的开发者、创业者或技术学习者。项目基于Vue技术体系,覆盖用户下单预约、服务项目展示、订单管理等核心业务页面;同时集成富文本编辑器与视频播放组件,可支撑图文介绍、视频案例等互动展示需求。压缩包大小66.31MB,共2000个文件,其中主要包含862个JavaScript脚本、546个Vue组件、79个HTML页面和53个CSS样式文件,另配有350个Markdown说明文档、91个JSON数据文件及SQL数据库脚本,方便理解接口结构、页面逻辑与数据持久化方案。已有238人查看学习,整体目录结构清晰,既适合快速启动同类项目演示,也可作为入门真实业务前端开发的参考,能有效缩短二次开发周期。
1. 同城上门家政按摩 H5 小程序源码:这套上门预约系统到底值不值得下
做本地生活服务这两年,上门家政、按摩、陪诊这类预约单子的痛点其实不在“需求”,而在“派单链路”:客户要的是一键约到人,商家要的是把单派给最近的人还能盯住服务状态。这份“同城上门家政按摩H5小程序源码 上门预约系统.zip”打包的就是一整套可直接改造成运营项目的 H5 端 + 小程序端预约系统,含前后端,不是只有一个页面壳子。你拿到手能跑通的不只是下单,还有服务人员的接单、上门打卡和后台核销这一整条闭环。适合三类人:想快速搭一个同城上门服务 Demo 去谈客户的开发者,正在给实体家政/按摩门店做数字化转型外包的单干工程师,以及想研究微信生态内预约单支付闭环的产品或运营。先说一个反直觉的结论:这套系统最值钱的地方大概率不是下单页面的交互,而是藏在后端“服务状态机”和“分账回调”里的业务逻辑,后面我会逐层拆给你看。
2. 技术栈摸底:先看清这套预约系统的双端骨架和几个关键选型
2.1 前后端到底用了什么,为什么这个组合最适合上门预约场景
拆包之前先聊选型。这套系统前端分两个入口:一个是跑在微信里的原生小程序端,一个是 H5 端的响应式页面。小程序端和 H5 共用同一套后端接口,这种“双端共用一个后端”的架构在本地生活类项目里非常常见,因为业务不复杂,没必要为两个前端单独搭服务。后端这边,常见的做法是用 Java Spring Boot 或 PHP ThinkPHP 这类框架提供 RESTful API,配合 MySQL 存储订单和用户数据。为什么这个组合适合上门预约?三个理由:第一,预约系统的核心不是并发抢购,而是状态流转,Spring Boot 自带的状态管理和事务机制足够应对;第二,MySQL 对这种结构清晰的业务表支持极好,订单表、技师表、用户表之间的关联查询效率高;第三,H5 端和小程序端都能用同一套 Token 鉴权方案,省掉大量重复开发。
预约系统里有个隐含的技术需求容易被忽略:位置匹配。用户下单要选服务地址,系统要把订单推给“距离最近且当前空闲”的服务人员。这套源码里如果你看到经纬度字段,那说明它用的就是最原始的“两点间距离排序”方案。这种方案在单量不大时完全够用,不需要引入高德地图的逆地理编码或者距离矩阵 API,也省了一笔地图服务费。如果你后续业务量大了,可以再替换成基于 Redis GEO 的方案,但现在这个阶段,简单排序反而是最稳的选择。
2.2 核心功能模块拆解:从用户下单到服务完成,数据在哪些表之间流转
把源码里的 controller 层和 service 层捋一遍,能看出这套系统的功能设计是围绕“一条订单的生命周期”展开的。我拆给你看这条链路:
用户在小程序端选择服务项目(家政保洁、上门按摩、陪诊等),选择上门时间,填写地址并支付。此时后端会做三件事:写入orders主表、写入order_items明细表、调用微信支付预下单接口。支付成功后,订单状态从“待支付”变为“待派单”。管理员或系统后台看到待派单的订单,根据服务地址的经纬度去technicians表里搜索在线且空闲的技师,推送接单通知。技师接单后状态变为“待服务”,上门后在后台或小程序端点击“开始服务”,最后用户确认完成并评价。整个流程里,orders表里的status字段从 0(待支付)到 4(已完成)的变化,是这套系统的命脉。你在改二次开发时,最先要维护的就是这个状态机,千万别随意改字段值含义,否则已发布的版本会出现订单卡死。
支付环节里有个值得注意的设计:分账。如果这套源码是支持平台抽成的,那payment表里大概率有profit_sharing标记位,用于区分一笔订单是全额进商家账户还是按比例拆分。这个细节容易被忽略,但对接微信支付分账功能时需要用到它。如果你只是做单店预约,不需要平台抽成,那这个字段可以直接忽略;如果你要做平台模式,就要提前想清楚分账比例存在哪个表。
3. 部署与配置:把双端项目在本地环境跑起来的五个关键步骤
3.1 环境准备与项目结构识别:先别急着导数据库,先确认三个配置文件
拿到压缩包解压之后,第一步不是看代码,而是看目录结构。一般的发布包会分成server(后端)、admin(管理后台)、h5(H5 前端)、mp(小程序前端)或者采用 uni-app 的单体项目结构。你先在根目录的 README 或者 SQL 文件里确认两件事:后端是什么语言写的、数据库是哪个版本。如果是 Spring Boot 项目,你会看到pom.xml或application.yml;如果是 ThinkPHP 项目,你会看到.env文件和application目录。这两个分支的环境区别很大。
确认后,按照下面的步骤初始化:
# 以 Spring Boot 后端为例,本地启动前的第一步是导入数据库 mysql -u root -p < database/init.sql # 然后修改配置文件,将数据库连接指向本地 # 路径一般在 server/src/main/resources/application.yml 或 application-dev.yml # 最后启动后端服务 cd server mvn spring-boot:run这里有个细节要提示:很多源码包的数据库 SQL 文件里的表前缀是固定写死的,比如wp_或者yzn_。如果你本地环境之前跑过其他项目,有同名表,导入时会发生冲突。我一般会在导入前先全局搜索CREATE TABLE把表前缀确认一遍,必要时全局替换你的前缀。另外,MySQL 版本之间兼容性也是个坑,这套源码压缩包里如果是 5.7 时代写的 SQL,在 MySQL 8.0 上导入时可能会因为字符集或默认排序规则不兼容而报错。常见的处理是手动把 SQL 文件里的utf8mb4_unicode_ci统一改成utf8mb4_0900_ai_ci或在建库时用SET NAMES utf8mb4。
3.2 前端配置与接口地址适配:小程序端和 H5 端的 baseURL 分别填什么
前后端的接口是对接的,小程序端和 H5 端各自会有一个配置文件来声明后端地址。在小程序端一般在utils/config.js或common/config.js里,H5 端大概率在src/config/index.js里。你需要把所有http://127.0.0.1或http://localhost替换成你本机的局域网 IP,因为手机上的小程序真机预览是无法访问电脑 localhost 的。替换时注意:微信开发者工具里如果不勾选“不校验合法域名”,你还必须在菜单栏里关闭这个验证选项,否则所有请求都会被拦。H5 端如果是 Web 项目,直接改 baseURL 并保证手机和电脑在同一局域网即可;如果是打包成 App,还得配 HTTPS。
// 小程序端 config.js 示例 // 本地联调时改用局域网 IP,这样手机真机上也能访问到你电脑上的后端服务 module.exports = { baseURL: 'http://192.168.1.101:8080/api', // 改成你自己的局域网地址 timeout: 10000, }上述配置改完后,先用小程序开发者工具编译一次。如果登录接口能返回 token,说明前后端连通了。如果报 404 或者 405,先查后端控制台日志,绝大多数原因是前端路径里的/api前缀和后端application.yml里的context-path不一致。确认这两个地方匹配,是个非常容易被忽视的细节。
3.3 后台管理系统的角色配置:管理员、技师、用户三种权限从哪分配
这套系统通常带一个 PC 端管理后台,用于管理员派单、技师审核、订单管理。后台的登录入口独立于小程序端,账号密码一般在 SQL 初始化脚本里预置。找到admin_user表,把里面的密码哈希值改成你自己的账号,或者直接用预置的账号登录后从后台修改。后台里最重要的设置是服务项目和技师的管理。服务项目决定用户在小程序端看到哪些品类,技能类型(如按摩、保洁、陪诊)需要和技师表里的skills字段对应上,否则技师接不到项目下的单。
权限配置上,系统通常走 RBAC 模型,即用户表、角色表、权限表三张表关联。这套源码里的权限粒度一般是“操作级”,比如“派单”权限和“审核技师”权限是两个独立条目。在后台里你不需要去动数据表里的权限记录,找到“角色管理”菜单,给对应角色勾选权限即可。如果后台没有内置“派单”功能,而是纯靠系统自动匹配,那需要检查定时任务和队列的配置,后面会单独说。
4. 核心业务逻辑:从支付回调到派单匹配,参数到底怎么调才稳
4.1 微信支付回调的配置与验签:签名算法和回调地址缺一不可
上门预约系统最不能出错的模块是支付。微信支付的对接流程是:后端调用微信统一下单 API 拿到prepay_id,返回给前端,前端拉起支付面板。用户支付成功后,微信服务器异步通知你的回调地址。这个流程里有一个常见的业务坑:把支付成功和订单处理完成混为一谈。支付成功只是说明钱收了,你的系统还需要在回调里做订单状态的更新和后续派单的触发。源码里这个逻辑通常写在一个名为NotifyController的类里,重点看它的鉴权逻辑。
// 支付回调处理伪代码 // 微信会以 POST 方式请求你的回调地址,必须验证签名 public String wxPayNotify(@RequestBody String xmlData) { // 1. 将 xmlData 转换为 Map // 2. 使用商户密钥对 Map 进行签名校验,防止伪造回调 Map<String, String> params = convertXmlToMap(xmlData); if (!WxPaySignature.verify(params, apiKey)) { return failResponse(); // 验签失败直接拒绝 } // 3. 检查订单状态是否是“待支付”,避免重复处理 String orderNo = params.get("out_trade_no"); Order order = orderService.getByOrderNo(orderNo); if (order.getStatus() == 0) { orderService.markPaid(orderNo); // 支付成功,状态置为待派单 dispatchService.dispatch(order); // 触发派单逻辑 } return successResponse(); // 告诉微信不要再回调了 }签名验证这一步是底线。有些开发者初学时图省事直接跳过验签,结果被人伪造回调刷单,损失惨重。支付回调地址需要在外网可访问的域名下才能收到微信的通知,本地联调时建议用内网穿透方案或直接把回调地址改成公网服务器的测试域名,但要选可信的工具,别乱装来路不明的客户端。参数上要注意:回调地址需要在商户平台配置,并且这里的apiKey是商户 API v3 密钥,不是 API v2 的密钥,两者混用是绝大多数对接失败的原因。
4.2 派单算法与技师状态管理:距离排序、忙碌标记和超时回收
支付完成后进入指派环节。常见做法是定时扫描orders表中状态为“待派单”且创建时间超过 1 分钟的订单,然后用一个简单策略找技师。策略通常是:在technicians表里过滤status = 1(在线)且is_busy = 0(空闲)的记录,再按距离排序。距离计算用的是经纬度差值平方和开方,不精确但够用。这套系统没有引入 Redis,也没有用消息队列,所以派单任务往往部署为 Linux 的 cron 任务或 Java 的@Scheduled定时任务。你拿到源码后,找task或job包,把 cron 表达式确认一下即可。
参数调整上,有两个值值得关注:超时未接单时间和预约时间窗口。超时未接单时间一般设置 3 到 5 分钟,如果超时后没有技师接单,系统应自动把订单标记为“未接单”并向管理员发送通知。预约时间窗口控制用户能选择未来多少小时内的服务时间,家政行业常设为 2 到 24 小时。这俩参数有的写死在常量类里,有的写在后台的配置菜单里。建议你在后台“系统设置”里找到这两项,改成你业务实际需要的值。
4.3 状态机流转与并发控制:同一笔订单被重复接单了怎么办
上门服务有个经典并发问题:两个技师同时抢同一张订单。如果派单逻辑里没有加锁,数据库层面就会产生“一单多接”的脏数据。这套源码里防御写法通常有两种:一是把orders表的technician_id字段加一个UPDATE ... WHERE status = 1的乐观锁条件,二是用 MySQL 的行级锁SELECT ... FOR UPDATE锁住订单行。我看过的多数普通源码包用的是前者,逻辑简单且不容易死锁。你在二次开发时,可以把这一句写在dispatchService里,确保更新时再次校验status状态。
-- 乐观锁更新示例 -- 只有订单状态仍为“待派单”时,才允许指派技师 UPDATE orders SET technician_id = 5, status = 2 WHERE id = 20240801001 AND status = 1;只要影响了 1 行,说明抢单成功。如果影响行数为 0,说明订单已经被其他人接了。这种做法不需要引入 Redis 分布式锁,对本项目的并发量来说是恰到好处的。如果你未来单量涨到每秒几十单,再考虑用 Redis 锁或消息队列。现在这个阶段,性能瓶颈不会出现在抢单,而是出现在支付回调的重复通知上。
5. 避坑与常见问题:这套上门预约系统最容易翻车的五个地方
5.1 数据库导入字符集报错:原因不明就乱改 SQL,越改越乱
现象:导入 SQL 文件时提示Unknown collation: utf8mb4_0900_ai_ci或中文乱码。
原因:源码打包时的 MySQL 版本和本地版本不一致。utf8mb4_0900_ai_ci 是 MySQL 8.0 的默认排序规则,而 5.7 版本只支持 utf8mb4_general_ci。有些新源码包是在 8.0 下导出的,本地如果是 5.7 就会直接报错。反之,有些老源码包用了 latin1 或 utf8 混排,在 8.0 下导入则会出现乱码。
解决:打开 SQL 文件全文搜索COLLATE,把所有utf8mb4_0900_ai_ci替换为utf8mb4_general_ci。同时保证文件头部有SET NAMES utf8mb4。重新导入前,建议先DROP DATABASE再重建,如果你不清理干净,二次导入会有残留表。从那以后我每次导入 SQL 都会先查版本再执行,从不在源文件上直接乱改。
5.2 小程序端图片加载不出来:这是路径写死的问题,不是代码 bug
现象:小程序端服务项目页面的图片裂开,登录页背景图消失,但网页端显示正常。
原因:源码包里的图片资源可能使用了绝对路径或相对路径混合。如果你是用开发者工具打开小程序,域名校验会拦截非 HTTPS 图片请求;如果图片路径写的是根路径/uploads/...,在 H5 端正常,在小程序端会被当成本地路径解析,从而失效。
解决:把前端配置里的imgBaseUrl字段统一改为后端公网地址,并确保uploads目录通过 Web 服务器可访问。在开发者工具中勾选“不校验合法域名”只是临时手段,真正上线前必须配置微信小程序后台的 downloadFile 合法域名。另外注意image组件的src属性不能为空字符串,有些代码在数据未加载时给空串会导致整个列表渲染异常,建议在初始数据里给一个占位图 URL。
5.3 支付回调收到但订单状态不更新:日志里全是验签失败
现象:用户在小程序端确实付了钱,但后台订单仍显示“待支付”,查日志发现回调请求报签名错误。
原因:最常见的有三种:一是回调地址暴露了查询参数(如?debug=true),微信在拼接签名时包含了这些参数,导致验签不过;二是后端解析回调时读取了错误字段,把transaction_id和out_trade_no搞反了;三是apiclient_key.pem和apiv3_key的配置路径写错,项目根本读不到正确的密钥。
解决:先检查回调地址是否与商户平台配置完全一致,且不带任何自定义参数;再检查后端的WxPayConfig里的两个密钥配置是否分别指向了 v3 和 v2 的字段,两者绝不能互换;最后开启回调日志,把微信 POST 的原始 XML 打出来,对照接口文档逐字段核对。如果还是验签失败,优先怀疑服务器时间偏差过大,微信签名的 timestamp 校验在时间偏移超过 5 分钟时会直接拒绝。
5.4 技师接单后无法“开始服务”:状态没有遵循顺序流转,用户只能干等
现象:技师在手机上点击“开始服务”按钮,系统提示“操作失败”或“非法状态”。
原因:上门预约系统的状态机是强顺序的,从“待服务”到“服务中”再到“待完成”。如果你跳过了某个中间态,比如直接从“已接单”点“完成”,后端状态机校验会直接驳回。还有一种情况是技师接单前,管理员在后台手动修改过一次订单状态,导致前端展示的状态和后端不一致,此时按钮点击时会带着旧的订单状态去请求,同样会被拒绝。
解决:进入service层找到状态流转方法,检查是否在更新前校验了当前状态。建议在后端写一个状态机校验表,明确规定每个状态允许跳转的下一个状态。我一般会在orders表新增一个status_historyJSON 字段,记录每次状态变更时间和操作人,方便排查类似问题。
5.5 订单超时未派单却没有通知:定时任务漏配了时区或执行周期
现象:用户下单后一直处于“待派单”状态,前台不推单,后台也不提示。
原因:定时任务没有正常启动。常见原因有两个:一是配置了 Linux crontab 但服务器的时区不是 Asia/Shanghai,导致任务在错误的时间点执行;二是源码里的@Scheduled注解默认只支持单线程执行,如果其中一个任务卡死,后面的派单任务会被阻塞。
解决:查看启动类或任务配置类,确认是否遗漏@EnableScheduling注解;如果用了 XML 配置 cron,检查是否有空格符写错。建议在任务方法的第一行加入一行日志,每 30 秒输出一次,确认调度确实在执行。如果并发量上来后担心阻塞,用线程池配置taskScheduler,给定时任务单独开一个池,别让它和业务线程共用池。解决完再看看控制台有没有输出,如果没有,多半是 Spring 容器启动时没扫到任务类的包名。
6. 进阶玩法:把一套通用源码改造成熟人家庭单模式的三个关键改动
拿到这套源码后,先别急着原样运营,先做一次需求收敛。以家政按摩行业为例,最典型的运营场景从“平台派单”切换成“熟人家庭单”:即客户固定联系某一位技师,技师直接接单上门的模式。这个玩法不需要复杂的派单算法,反而更考验“锁定关系”的设计。改动集中在三块:
第一,在orders表新增favorite_technician_id字段,用户下单时如果选择“指定技师”,后端强制校验该技师与服务项目是否匹配。核心改动在前端的下单页,把服务人员选择从“推荐列表”改为“我的收藏技师”单选,这个改动只需改一个页面文件。第二,派单逻辑改成“直连”模式:当订单带有favorite_technician_id时,跳过派单算法,直接调用推送服务通知该技师。推送这里保留原有的微信订阅消息模板即可,但要新增一条发送记录到message_logs表,方便追溯。第三,后台增加“家庭单报表”,统计熟客复购率,你需要把orders表里的user_id和technician_id做一次 GROUP BY,按月和按人聚合。SQL 不复杂,但很多通用源码后台没这个报表,加一个页面拿到数据很有说服力。
这里的难点是,你要分清哪些改动影响核心链路,哪些只是页面调整。指定技师这个改动直接影响订单创建、支付回调、派单三个环节,需要同时修改后端接口字段、数据库表结构、前端提交参数三处,缺一个就会出现订单创建成功但指定技师没有收到通知的诡异现象。我建议你按“先加字段,再改后端接口入参,最后改前端页面”的顺序推进,每走一步就用 Postman 打一次接口,别一次性改完再联调。如果后台得过且过,很多问题要到用户真实下单才会暴露。
额外一个建议:把派单超时时间从 3 分钟改到 10 分钟。熟人家庭单的场景下,技师和客户有微信联系,客户不会像平台单那样在 3 分钟内急着等接单确认,技师可能在忙别的活,10 分钟更符合人体工学的反应节奏。这个参数不需要找代码,后台设置里改一下即可,但也正因为它太容易改,很多人忽略了对超时后通知的配置。我后来养成的习惯是每改一个参数,就在测试环境跑一遍“下单到完成”的全流程,特别是改完状态机和支付回调后,这两块必须完整验证。从那以后我每次接手一个预约类源码包,都强制自己走一遍全流程再交付,这种项目翻车大多翻在细节上,希望帮到你。
本文还有配套的精品资源,点击获取