简介这是一套食刻外卖系统的完整整站源码面向外卖平台开发者、创业者及技术学习者可用于搭建覆盖用户下单、商家管理、骑手配送与小程序/APP触点的全链路外卖业务。资源压缩包共2000个文件以1490个JavaScript逻辑脚本、419个HTML页面和84个样式表文件为主辅以7个XML配置文件整体体积136.95MB目录结构清晰便于按功能模块检索与部署。系统包含商户端、配送端、用户端以及小程序和APP源码后端接口与前端界面齐备其中APP采用原生与网页混合开发模式兼顾性能与迭代效率小程序源码可直接对接微信生态降低获客门槛。开源特性允许开发者自由获取、修改与再分发既能用于快速搭建可运营的外卖平台也可作为学习高并发订单处理、接口设计与移动端适配的实战范本。目前已有933人学习下载适合不同经验层级的开发者根据自身业务需求进行定制化改造与二次开发。1. 整站源码食刻外卖系统一套能直接上线的多端闭环做过外卖相关项目的人应该都有体会市面上能下到的外卖源码不少但真正敢说“完整”的并不多。大多数要么只有用户端小程序后台简陋得像个 demo要么商户端和配送端是拼凑的数据库还不统一。我拆过这套食刻外卖系统源码之后确认它在结构上确实对得起“整站”两个字——用户端小程序、独立商户端、配送骑手端、平台管理后台加上 APP 壳工程全部开源能串成一条完整的业务闭环。适合想研究外卖业务流程的开发者也适合准备做本地生活服务、校园外卖、社区团购配送的中小团队。我按生产环境的标准把它复现了一遍这篇就写清楚它由哪些部分构成、怎么部署起来、以及那些没人告诉你的坑。2. 五个端口一脸懵先从多端角色与通信机制下手2.1 系统里每一端到底扮演什么角色第一次接触多端源码的人最容易犯的错是把“商户端”和“管理后台”当成一回事。食刻外卖系统里至少有四个截然不同的角色入口用户在小程序里下单商户在商户端里接单、出餐、打印小票骑手在配送端里抢单、取货、送达平台方在管理后台里管商户审核、订单抽成、优惠活动配置。还有一层 APP 壳是给用户端和管理端打包成安卓、iOS 应用用的不是独立的第五端。拆这份源码时建议按“订单数据流向”去看代码别按目录结构看。用户提交订单之后订单表里会写入一条记录接着通过消息队列或者 WebSocket 推送给对应商户商户接单后系统再把订单状态变成“待配送”并广播给附近的骑手骑手抢单、取货、送达每一步都回写订单状态。把这套流程捋顺了五端之间的数据关系就清晰了。2.2 服务端与客户端的通信方式不是只有 HTTP源码里用户端和配送端的实时性要求高我用一台部署了 ThinkPHP 框架的服务端做了测试。客户端向服务端发请求走的是标准的 HTTP REST 接口比如用户登录、下单、查询订单列表这类操作。但订单状态变更、骑手抢单这类实时性强的场景用的不是 HTTP 轮询而是 WebSocket 长连接。我在商户端和配送端的源码里都找到了 WebSocket 客户端的实现服务端对应有一个Workerman或者Swoole常驻进程来维持连接。这里有个容易踩的坑本地部署时只在 CLI 模式下启动了 WebSocket 服务站点在 Nginx 里也监听了 80 端口但两者互不干扰。如果 WebSocket 服务没有以守护进程方式跑起来商户端就会一直停在“等待接单通知”的假死状态页面上看不出任何报错。# 进入项目根目录启动 WebSocket 服务常见做法是放在 public 目录外 cd /www/wwwroot/shiike_server php think worker:start -d # 检查端口是否已被监听 netstat -tunlp | grep 9501-d参数表示以守护进程方式运行这样终端关闭后服务不会中断。端口 9501 是我在config/workerman.php里看到的监听配置如果你的环境不同以上面这一步的实际输出为准。2.3 数据库表之间的关联字段设计这套系统最值得看的是它订单相关表的结构尤其是多商户订单的拆单逻辑。一个购物车里如果同时选了 A 店和 B 店的商品食刻源码会把这单拆成两条订单记录order_no做主订单号sub_order_no做子订单号两个字段都有但只有在订单表里查parent_id 不为 0的记录才是被拆出来的子单。这种设计在源码里表现为order表和order_goods表的一对多关系订单在商户端显示时也是按子订单维度去查的。做二次开发的时候千万不要在子订单里再插一条order_no就完事很多调用都是直接用order_no查事务记录的一旦撞单对账就会出问题。3. 本地部署起来环境搭建与前后端分离的第一步3.1 从零把服务端跑起来的五个步骤部署这套食刻外卖系统推荐直接上宝塔面板操作因为它有两部分代码需要跑在同一个 Web 环境中一部分是服务端 API 接口一部分是平台管理后台的静态页面。管理后台不是前后端分离的它是一套 PHP 渲染的模板所以必须把站点根目录指向/public否则路由全部失效。# 以宝塔面板新建站点为例 # 1. 创建站点时选择 PHP 7.2运行目录改为 /public # 2. 设置伪静态ThinkPHP 的规则是 # location / { # if (!-e $request_filename) { # rewrite ^(.*)$ /index.php?s$1 last; # } # }导入数据库这一步直接在 phpMyAdmin 里把sql目录下的.sql文件执行一遍。注意执行之前检查文件编码如果是utf8mb4数据库排序规则也要选带utf8mb4_general_ci的否则中文乱码会让你排查一上午。执行完把.env文件里的数据库账号密码改成你自己的。3.2 小程序的编译与对接用户端小程序是uni-app工程导入微信开发者工具之前要用 HBuilderX 或命令行先跑一次依赖安装。核心配置都在common/config.js文件里要把baseUrl改成你自己服务器的 IP 或域名而且必须配置合法域名普通 HTTP 地址在开发者工具里能用真机上就会被拦截。// common/config.js 关键配置段 const config { // 你自己服务器的 HTTPS 域名别用 IP baseUrl: https://yourdomain.com/api, // 腾讯地图 Key配送端和用户端都依赖它做地址解析 mapKey: 你的腾讯地图开发者Key }与餐饮相关的项目几乎都绕不开腾讯地图或者高德地图的 Key。食刻源码里配送端、用户端都调了地图 SDK如果不配置 Key页面能进入但地址搜索出来的坐标全是 0。申请 Key 时注意把 WebServiceAPI 和微信小程序两个 service 都勾上否则接口会报 401。3.3 商户端和配送端的启动差异商户端源码虽然是同样的结构但它依赖的设备能力比用户端多最典型的是小票打印。商家接单后系统会把订单推送至小票打印机源码里用了escpos系列指令集。如果本地没有对应型号的打印机商户端会不断提示“打印失败”容易让人误以为接收订单也出了问题。建议测试阶段在商户端的设置里把自动打印开关关掉只保留气泡提示。配送端需要 GPS 定位权限源码里用的是 uni-app 的uni.getLocation接口。在开发者工具里这个接口能正常返回但真机上要求调用者必须全局声明requiredPrivateInfos字段并配置getLocation这些在源码的manifest.json注释里提到了——如果你下载的版本里没有需要自己在对应的配置块里补上requiredPrivateInfos : [ getLocation, chooseLocation ]这段配置不补安卓真机一打开配送端就黑屏iOS 直接提示隐私权限缺失血泪经验。4. 订单状态机与余额结算逻辑改写前的必修课4.1 订单能走到哪一步谁说了算接单流程不是简单的几个字段改改就好它涉及状态机、库存表和流水记录三方的联动。食刻源码里把订单状态定义在下单时的order_status字段中约定是10 为已支付待商户接单、20 为商户已接单待骑手取货、30 为骑手已取货配送中、40 为已完成、50 为已取消。我建议你在下手改业务前先把这个枚举彻底搞懂否则后面改一个状态身边的判断就崩了。我在测试时试过把订单从待接单直接改成配送中结果商户端、用户端都正常但配送端一直不弹新任务后台也看不到骑手轨迹。原因就是配送端的任务列表不是查order_status而是查一张独立的delivery_task表这张表靠事件触发写入。状态靠手动改 SQL 跳跃这是条单行道不走业务接口就不会生成新记录。-- 正确触发配送任务生成的方式走源码的接口 -- 接口路径/api/order/assignDelivery -- 前置条件商家已接单且订单状态为20 -- 服务端会同时执行订单状态更新写task表发WebSocket通知三件事4.2 商户结算和用户余额是两套账很多外卖系统最容易崩的地方在金额计算这套源码设计得干净一点的是商户账户余额和用户账户余额用的是两张表分别是merchant_wallet和user_wallet。订单完成后用户端的支付记录已经扣款商户端的入账要走一条单独的“订单完成结算”逻辑通常是 T1 结算也就是说订单完成当天不会立刻进商户余额而是进入一个settlement_pending待结算字段。做二次开发时这个地方最容易算错的就是拼单场景。两个子订单分别属于不同商户系统结算时是按子订单的merchant_id独立结算的。如果你按主订单的金额一次性入账第一个商户的余额就会多出一倍。源码里涉及结算逻辑的文件有详细注释改之前先把config/settlement.php里的settlement_mode配置看明白。5. 避坑排查手册从部署到上线最常见的五类问题5.1 小程序真机调试连不上本地接口现象开发者工具里接口正常返回数据但手机扫描预览后所有请求全部失败。原因腾讯小程序平台只能向 HTTPS 域名发起网络请求且域名必须在后台配置白名单。解决本地开发时打开开发者工具的“不校验合法域名”选项但要测试真机建议直接申请一套测试域名部署上去跑。提示用 IP 端口的方式在安卓机上临时也能访问但 iOS 完全不认这种方案别在这上面浪费时间。5.2 后台登录后所有页面 404现象管理后台能进登录页admin 账号密码验证成功后跳转首页随后所有菜单点开都是 404。原因站点根目录绑定错了宝塔创建站点时如果默认绑定了项目根目录而没绑定/publicThinkPHP 的路由就找不到控制器。解决删除原站点重新绑定或者修改 Nginx 配置里的root路径指向public目录后重载配置。5.3 商户端长时间不刷新就收不到新订单现象商户端挂机一小时后新订单完全不弹出刷新页面后那笔订单才出现在列表里。原因WebSocket 服务挂了或者 Nginx 对长连接有 60 秒的空闲超时断开了连接。解决重新启动 worker 守护进程并在 Nginx 的 server 配置中加上proxy_read_timeout 3600s;这样一条配置否则连接保持不够久夜间长时间不操作窗口照样掉线。5.4 配送端定位偏移了五百米现象骑手在 A 点打开配送端地图上自己的人像点却出现在五百米外的马路上。原因这套源码的定位信息走的是腾讯地图提供的 GPS 坐标真机上拿到的是 WGS84 坐标坐标系不同导致偏转。解决在腾讯地图控制台把 Key 的应用类型选成“微信小程序”并在 map 组件的coordinate-type属性中显式传入定位坐标类型切记不要两个值混用。5.5 用户支付成功但订单状态没变现象微信支付回调日志显示支付成功但小程序的订单一直是“待支付”。原因支付回调地址没有配置或者配置文件里的回调 URL 与微信商户平台后台不一致导致回调通知压根没送达到你的服务器。解决检查config/wxpay.php里的notify_url再对照微信商户平台里的 API 安全设置逐字符比对一遍。6. 上线前最后的加分项把配送范围判定从矩形换成多边形外卖系统做完部署、功能全部走通之后业务上最容易收到的反馈之一就是“我家和店里就隔一条街偏偏不能下单”。这是因为源码默认的配送范围是商家后台设置的一个矩形经纬度边界也就是min_lat, max_lat, min_lng, max_lng四个值硬算出来的判断。我一般会在上线前把它替换成 Geofencing 多边形判定用一个简单的射线法算法判断用户坐标是否落在商家圈出的任意多边形内这样商户在后台随便画圈前端就能精确算范围。第一步把商家配送范围的存储字段改成一个JSON类型字段例如delivery_area存一串经纬度数组。第二步在服务端写一个射线法公共函数它接受用户的经纬度和商家的多边形坐标数组返回布尔值。射线法的原理是过待判断的点画一条水平射线统计与多边形边的交点数奇数在内部偶数在外部。第三步在创建订单的接口里只加一条 if 判断再把新的异常提示翻译成用户看得懂的话——超出范围时提示的具体门店名而不是一句干巴巴的“不在配送范围”。这一步做完以后后台商家的投诉率会明显下降搜索关键词“配送范围判定”时这也是一个高频技术点。从那以后我再做任何有定位属性的订单系统都强制把配送范围写死在服务端校验前端地图上画的圈只用来展示不信任何传入的地图多边形参数做判断。绕过接口直接下单的安全性也得靠服务端的二次校验来兜底。希望这份装机笔记能帮你少走几趟弯路。本文还有配套的精品资源点击获取 SEO 优化官网定制响应式建站教育培训建站