ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

养生足浴预约小程序源码:预约排班与订单状态机实战

养生足浴预约小程序源码:预约排班与订单状态机实战 简介这份养生足浴预约小程序源码面向足浴、养生馆等线下服务门店的经营者与小程序开发者用于快速搭建一套在线预约系统解决门店消费频次高、技师排班与到店核销管理繁琐的问题。功能覆盖本店动态、养生知识展示、养生项目预约、技师预约后台支持预约项目人数与时段设定、预约名单导出、名单管理与核销采用腾讯小程序云开发方案无需自备服务器和域名。资源包为zip格式共487个文件约3.13MB其中186个js承担业务逻辑与云函数105个wxss与82个wxml负责页面样式与结构70个json用于配置另有38张png与1个gif作为界面素材并附安装使用手册文档。目前已有1968人学习下载适合希望低成本上线预约功能、参考完整前后端实现或进行二次开发的读者。1. 养生足浴预约小程序从预约混乱到工单闭环这套源码能省掉多少重复造轮子的时间上周帮朋友看了一家连锁足浴门店的排钟表前台还在用纸质本子记“888号房李姐20:30加钟40分钟”一到周末高峰期三个店员同时接电话、翻本子、喊技师错单率肉眼可见地往上飙。这不是个例本地生活服务类门店——足浴、推拿、采耳、SPA——只要SKU里带“技师房间时长”三个变量纯手工排期基本撑不过日均30单。这套《养生足浴预约小程序源码.zip》要解决的就是这个场景把选项目、选技师、选时段、下单支付、到店核销、加钟续单串成一条线上工单流前台只负责确认不再负责记忆。它适合谁一是手里有实体门店、想低成本把预约搬到微信生态里的经营者二是接外包单子的开发者客户预算不高但要求“能跑起来、能改、能上线”这套源码可以当交付底座三是想学小程序完整业务闭环的练手者它比商城类项目轻但订单状态机、时段冲突检测、技师排班这几个点一个不少。源码包本身是工程文件不是可执行安装包拿到手需要自己配环境、导数据库、改配置下面按我实际拆包的顺序讲清楚怎么落地。2. 工程结构与技术栈拆解先看清哪些能直接用哪些必须换2.1 目录分层与前后端边界解压后先别急着打开开发者工具用文件管理器把顶层目录过一遍心里有个地图。这类预约小程序的典型结构是前后端分离小程序端一个目录服务端一个目录数据库脚本单独放。我拿到的包大致是这样yang-sheng-zu-yu/ ├── miniprogram/ # 微信小程序前端工程 │ ├── pages/ # 页面首页、项目列表、技师选择、时段选择、订单、我的 │ ├── components/ # 公共组件日历、时段格子、技师卡片 │ ├── utils/ # request 封装、日期格式化、金额计算 │ ├── app.js # 全局登录态、用户信息 │ └── app.json # 页面路由、tabBar、权限声明 ├── server/ # 服务端工程 │ ├── controller/ # 业务入口预约、订单、技师、门店 │ ├── service/ # 核心逻辑时段冲突、排班、加钟 │ ├── model/ # 数据模型 │ ├── config/ # 数据库、微信 appid/secret 配置 │ └── app.js # 服务启动入口 ├── sql/ │ └── init.sql # 建表 初始数据 └── README.md # 部署说明往往写得比较简略前端用原生小程序语法没上 uni-app 或 Taro好处是依赖少、编译快坏处是如果你要同时出支付宝或抖音端得自己重写。服务端看 controller 和 service 的写法大概率是 Node.js Express 或 Koa 那一套数据库 MySQL。判断依据是 config 目录里通常有db.js或database.js里面写着 host、user、password、database 四个字段。提示先确认服务端运行时。打开server/package.json看dependencies里是 express 还是 koa看scripts.start是什么命令。这一步决定你后面装 Node 版本和启动方式别跳过。2.2 数据库表设计与预约核心字段预约类系统的命门在表结构尤其是时段和订单两张表。把sql/init.sql用文本编辑器打开重点看这几张表表名作用关键字段service_item足浴项目id, name, duration, pricetechnician技师id, name, level, statusschedule排班/可约时段id, tech_id, date, start_time, end_time, statusorder订单id, user_id, item_id, tech_id, appoint_time, statusroom房间可选id, name, capacityduration字段是分钟数比如“中式足浴60分钟”就是 60。schedule表的status一般用 0/1/2 表示可约、已约、锁定。order表的status是状态机核心待支付、已支付、已到店、服务中、已完成、已取消。这几个状态怎么流转决定了你后面改代码时不能乱动哪里。常见做法是用户下单时先查schedule有没有冲突没有就写一条order并把对应schedule置为已约支付回调里再把订单状态推到已支付。如果源码里没有支付回调只做了模拟支付那上线前必须补微信支付 v3 的接口这是绕不过去的。2.3 环境准备与依赖安装动手前把工具备齐微信开发者工具稳定版即可、Node.js看 package.json 里的 engines 字段没有就选 16 或 18 LTS、MySQL 5.7 或 8.0、一个能跑本地服务的终端。顺序是先起数据库再起服务端最后开小程序。# 1. 建库并导入初始数据 mysql -u root -p -e CREATE DATABASE yangsheng DEFAULT CHARACTER SET utf8mb4; mysql -u root -p yangsheng sql/init.sql # 2. 进入服务端目录装依赖 cd server npm install # 3. 改配置数据库连接和微信参数 # 编辑 config/db.js 或 config/index.js # 把 host/user/password/database 改成你本地的 # 把 appid 和 secret 换成你自己的小程序账号里的 # 4. 启动服务 npm run start # 或 node app.js看 package.json 里 scripts 怎么写的utf8mb4不能省技师姓名、项目名里可能有生僻字或 emoji用 utf8 会报错。npm install如果卡住先换国内镜像源再装。服务起来后终端会打印监听端口通常是 3000 或 8080记下来下一步要填到小程序里。2.4 小程序端配置与首次运行打开微信开发者工具导入miniprogram目录AppID 填你自己的测试号或正式号。然后找utils/request.js或app.js里的baseUrl把http://localhost:3000填进去。本地调试时开发者工具右上角“详情 → 本地设置”里勾上“不校验合法域名”否则请求会被拦。// utils/request.js 典型写法 const BASE_URL http://localhost:3000; // 本地调试用上线换成 https 域名 function request(options) { return new Promise((resolve, reject) { wx.request({ url: BASE_URL options.url, method: options.method || GET, data: options.data || {}, header: { content-type: application/json }, success: (res) { if (res.data.code 0) resolve(res.data.data); else reject(res.data.msg); }, fail: reject }); }); } export default request;这段封装很常见code 0表示业务成功其他值走错误分支。你要做的是确认服务端返回结构是不是{code, data, msg}不是的话两边对齐一下。跑通第一个页面——通常是首页项目列表——能拉到数据就说明前后端通了。这一步过了后面才是业务逻辑的调试。3. 预约核心链路时段冲突检测与订单状态机怎么改才不出错3.1 时段冲突检测的三种实现与选型预约系统最容易翻车的地方就是“同一技师同一时段被约了两次”。源码里一般会在service/order.js或类似文件里做检测常见三种写法第一种查schedule表有没有对应记录且status0有就锁。简单但要求排班表提前生成好灵活性差。第二种不依赖排班表下单时用appoint_time和duration算出结束时间去order表查该技师有没有时间重叠的未取消订单。灵活但并发下容易双写。第三种在第二种基础上加数据库唯一索引或 Redis 锁防并发。我一般会保留第二种做业务判断再补一个数据库层面的兜底。看源码用的是哪种如果是第一种门店临时加钟、改时长就会很别扭建议改成第二种。// 时段冲突检测基于订单表的时间重叠判断 async function checkConflict(techId, startTime, duration) { const endTime new Date(new Date(startTime).getTime() duration * 60000); // 查该技师当天所有未取消订单 const orders await Order.find({ tech_id: techId, status: { $in: [1, 2, 3, 4] }, // 已支付到服务中 appoint_time: { $lt: endTime, $gt: new Date(new Date(startTime).setHours(0, 0, 0, 0)) } }); // 逐条判断时间重叠 for (const o of orders) { const oEnd new Date(new Date(o.appoint_time).getTime() o.duration * 60000); if (new Date(startTime) oEnd endTime new Date(o.appoint_time)) { return true; // 有冲突 } } return false; }$lt和$gt是 Mongo 写法MySQL 里换成BETWEEN或。核心逻辑是新订单的开始时间早于老订单结束时间且新订单结束时间晚于老订单开始时间两个条件同时成立才算重叠。duration * 60000是把分钟转毫秒。这段代码要放在下单事务里检测通过再写订单否则并发下还是会撞。3.2 订单状态机与支付回调补全订单状态是业务的中枢神经改错一个状态后面核销、退款、统计全乱。源码里如果只做到“下单→模拟支付→完成”上线前必须补真实支付。微信支付 v3 的回调流程是用户支付成功 → 微信服务器 POST 通知你的notify_url→ 你验签 → 改订单状态为已支付 → 返回成功。// 支付回调处理简化示意实际需验签 app.post(/api/pay/notify, async (req, res) { const { out_trade_no, trade_state } req.body; if (trade_state SUCCESS) { const order await Order.findOne({ order_no: out_trade_no }); if (order order.status 0) { // 待支付 order.status 1; // 已支付 order.pay_time new Date(); await order.save(); // 同时把对应排班置为已约 await Schedule.updateOne( { tech_id: order.tech_id, date: order.appoint_date }, { $set: { status: 1 } } ); } } res.json({ code: SUCCESS }); // 必须按微信要求返回 });out_trade_no是你自己的订单号trade_state是支付状态。验签部分微信文档里有现成的库别自己手写。回调必须幂等——同一笔订单可能收到多次通知所以先查状态再改。res.json({code:SUCCESS})这行不能少否则微信会一直重试。3.3 技师排班与加钟续单的处理足浴场景里“加钟”是高频操作用户按完60分钟想再加30分钟前台得能快速操作。源码如果没做加钟你得在订单详情页加一个“续钟”按钮逻辑是查当前订单结束时间往后顺延30或60分钟再走一次冲突检测没冲突就生成一条子订单或直接改原订单时长和金额。排班这块如果源码是固定时段比如每60分钟一个格子遇到90分钟的项目就不好排。常见做法是把时段做成动态的按项目时长切分。比如营业时间12:00–24:00项目90分钟那可选开始时间就是12:00、13:30、15:00……依次推。这个逻辑在utils/date.js里改把固定数组换成按duration循环生成。注意加钟和改约一定要留操作日志谁改的、什么时候改的、改前改后是什么。门店纠纷大多出在“我没约这个点”上有日志才说得清。4. 避坑与排查上线前必须过的五道坎4.1 现象小程序请求全部失败报“不在以下 request 合法域名列表中”原因本地调试没勾“不校验合法域名”或者上线后baseUrl还是http://且域名没备案。 解决开发阶段在开发者工具里勾选跳过校验上线前把服务端部署到已备案的 https 域名并在小程序后台“开发管理 → 开发设置 → 服务器域名”里把 request 合法域名配上。域名必须是 https且不能带端口除非 443。4.2 现象下单成功但技师时段没被占用同一时段还能再约原因下单和排班更新不在同一个事务里或者冲突检测只查了排班表没查订单表。 解决把冲突检测和写订单、改排班放进一个数据库事务如果用的是排班表方案确保下单成功后立刻把对应schedule的status改为已约别等支付回调。支付失败再释放。4.3 现象支付回调收不到订单一直停在待支付原因notify_url填的是 localhost 或内网地址微信服务器访问不到或者回调返回的不是微信要求的格式。 解决notify_url必须是公网可访问的 https 地址。本地调试可以用内网穿透工具临时映射一个公网地址这类工具很多选一个能生成 https 的即可。回调处理完必须返回{code:SUCCESS, message:成功}这类约定结构具体看微信文档。4.4 现象技师列表加载慢门店一多就卡原因每次请求都全量查技师表没分页也没缓存。 解决技师列表按门店 id 过滤加limit分页变动不频繁的数据可以放 Redis 缓存设 5 分钟过期。小程序端做骨架屏别让用户盯着白屏。4.5 现象用户手机号获取失败登录拿不到号原因getPhoneNumber接口需要用户主动点击按钮触发且小程序主体要完成认证非个人主体。源码里如果直接调wx.getPhoneNumber而没有按钮授权必然失败。 解决在“我的”页面放一个“授权手机号”按钮open-typegetPhoneNumber用户点击后再调后端解密接口。个人主体小程序拿不到手机号这是平台规则改不了只能引导用户手动填。5. 二次开发与验证把源码变成能交付的门店系统5.1 多门店隔离与数据权限单店跑通后下一步大概率是多门店。核心是给technician、schedule、order都加store_id字段所有查询带上门店过滤。服务端加一层中间件从登录态里取用户所属门店别让 A 店的前台看到 B 店的单。小程序端在首页加门店切换切换后重新拉数据。这一步改起来琐碎但必须做否则数据串了就是事故。5.2 核销与到店确认用户到店后前台要能快速核销。常见做法是订单详情页生成一个核销码数字或二维码前台在小程序管理端输入或扫码调order/verify接口把状态推到“已到店”。验证方法是用两个微信号一个用户端下单一个管理端核销看状态是否同步、排班是否释放如果服务完成。这个闭环跑通系统才算真正能用。5.3 上线前的检查清单检查项标准域名与 https已备案证书有效后台已配置支付真实商户号回调验签通过幂等处理数据库已开事务关键字段有索引tech_id, appoint_time日志下单、改约、加钟、核销都有记录权限多门店数据隔离管理端接口鉴权压测模拟 50 并发下单无超卖、无重复时段我自己的习惯是每次交付前拿两个手机、一个管理端把“下单→支付→到店→加钟→完成”完整走三遍中间故意断网一次、重复支付一次看系统扛不扛得住。这套源码的底子够用但支付和并发这两块十有八九要自己补。从那以后我每次接预约类项目都强制先把状态机和冲突检测画在纸上再动代码省下来的返工时间够喝好几壶茶。希望帮到你。本文还有配套的精品资源点击获取
返回列表