简介:本资源是一套完整的仿美团外卖微信小程序开源项目,面向前端初学者、全栈入门者及小程序实战学习者,旨在帮助开发者系统掌握小程序开发全流程与典型业务场景实现。压缩包共206个文件,含38个JS逻辑文件(处理页面交互与API调用)、34个WXML结构文件与34个WXSS样式文件(构建多端适配UI)、32个JSON配置文件(管理页面路由与自定义组件),辅以PNG/JPG图片资源及工具类、页面模块化目录(如_orderdetail、_submitorder、_address等),整体仅827KB,轻量易读。已有225人下载学习,代码结构清晰、模块职责分明,覆盖用户下单、商家管理、订单追踪、地址维护、退款申请、地图定位、微信支付对接等核心功能,可直接运行调试,是理解前后端协同、RESTful接口设计与小程序工程化实践的优质参考案例。 手头这份“仿美团外卖小程序-后端+前端代码.rar”,我前前后后折腾了大概两个晚上才把它彻底跑通。如果你是那种刚学完微信小程序基础、想找个完整项目练手,或者准备面试想让简历上多点硬货的开发者,这份代码确实值得花时间研究。它不是一个玩具Demo,而是把外卖业务的核心闭环都串了起来:用户端点单、购物车结算、订单流转、商家接单,后端该有的接口、数据库表、权限校验都齐了。不过说实话,因为这类打包资源通常缺文档、缺配置说明,直接解压后正常人都会一脸懵。
这几个月我一直在做一些前后端分离项目的实战拆解,外卖小程序属于典型的“看着简单、细节极多”的项目——但凡真正上手跑过一遍,你就会发现里面藏着大量文档里不会写、视频教程里不会讲的东西。所以这篇文章我尽量按实际操作的顺序,从解压后的目录结构开始讲,到后端怎么启动、前端怎么联调、业务链路怎么理解,最后再聊聊我在跑通过程中遇到的那些坑和二次开发的思路。文章适合已经有HTML/CSS/JS基础、了解一点后端接口概念的人,零基础的读者配合微信官方文档也可以跟着走,但建议先补一下JavaScript和基本编程常识。
1. 压缩包里到底装了什么:一份典型外卖项目的架构解剖
1.1 前后端代码目录:先搞清楚文件在哪,别急着打开IDE
很多人拿到压缩包的第一反应是解压然后双击“打开”,结果看到一堆目录直接懵掉。我先说一个通用规律:成熟一点的外卖项目,代码根目录下通常会分两个一级文件夹——backend(后端接口服务)和frontend(小程序前端源码),有的还会带一个sql或database目录用来放数据库初始化的SQL脚本。这类结构本质上是前后端分离的标准布局:前端只负责页面渲染和用户交互,后端只负责数据存取和业务逻辑,中间通过HTTP接口通信。
拿我手里这个项目举例,后端目录里能看到典型的Spring Boot工程结构:
src/main/java下按controller(接口层)、service(业务层)、mapper或dao(数据访问层)分包;src/main/resources里放着application.yml(配置文件)、mapper目录下的XML文件等。
前端目录则是一个标准的微信小程序工程:
pages目录下面按业务模块分子目录,比如index(首页)、cart(购物车)、order(订单)、user(个人中心);components目录放自定义组件;utils目录放请求封装、工具函数。
为什么强调先看目录?因为不懂结构,后面所有配置和联调都会像无头苍蝇。你改了后端的端口,却不知道前端在哪里配baseURL,这就是没搞清目录结构造成的。先花二十分钟把目录过一遍,给每个目录写下一句话注释,这个时间花得非常值。
1.2 技术栈选型:为什么外卖类小程序普遍是“Spring Boot + 原生小程序”
我看过不少仿外卖类项目,包括这个压缩包,技术栈高度趋同:后端用Spring Boot,前端用微信小程序原生框架,数据库用MySQL,缓存用Redis。这背后其实有非常现实的原因,而不是巧合。
Spring Boot在Java后端领域的地位不用多说,它最大的优势是起步快、生态全、坑少。外卖系统涉及用户鉴权、商品管理、订单状态流转、支付回调、消息推送等一系列复杂业务,Spring Boot成熟的生态能让开发者把精力集中在业务逻辑上,而不是纠结框架怎么集成。如果你用的是Node.js的Express或者Koa,写起来确实轻量,但很多轮子得自己造或者自己拼,项目复杂度上来之后对工程能力的要求高不少。
前端用原生小程序而不是uni-app或Taro,核心原因是外卖这类业务和微信平台的耦合度非常高。微信登录、微信支付、位置定位、订阅消息,这些能力原生框架支持得最好,调用也最直接。跨端框架虽然能一套代码多端发布,但在涉及微信私有API时经常要写条件编译,反而增加了复杂度。
有人可能会问,怎么很少见用若依这类后台管理框架做外卖后端的?实际上我见过,有些仿外卖项目的后台管理系统确实直接基于若依改的。若依自带用户权限、菜单管理、代码生成,拿来做管理后台很顺手。但是这个压缩包里的项目明显更偏简洁风,没有引若依,我觉得这反而是好事——核心业务代码更纯粹,学习成本也更低。你先把纯Spring Boot版本跑通了,以后真要接若依,那就是向后端工程里引入依赖、搬代码的事,思路是通的。
1.3 数据库设计速览:表与表之间的关系是理解业务的最好入口
几乎所有外卖项目的核心都藏在数据库表设计里。拿到压缩包后,第一步应该去读SQL脚本而不是读代码。这不是空话——表结构能直接告诉你系统有哪些角色、哪些业务、边界在哪里。
外卖项目的SQL脚本里,你大概率会看到这些核心表:
user:用户表,包含昵称、头像、手机号、openid(微信唯一标识);shop或store:商家表,包含店名、营业时间、起送价、配送费;product或dish:商品表,包含所属门店ID、名称、价格、图片、库存;cart:购物车表,记录用户加购的商品和数量;order:订单主表,记录订单号、用户ID、商家ID、总金额、状态;order_detail或order_item:订单明细表,记录订单中每个商品的快照信息;address:收货地址表;shipping_address:可能还有配送地址相关字段;coupon:优惠券表(有些项目有,有些没有)。
这些表之间最核心的关系是:用户下单时,系统从购物车读取商品信息,生成订单主表和订单明细表,然后清空购物车。订单主表管的是“这笔订单的全局状态”,订单明细表管的是“这笔订单里具体买了哪些东西”。为什么要两个表而不是一个表存所有商品?因为一个订单可能包含多个商品,而数据库第一范式要求字段不可再分,拆成主表和明细表是最经典的设计方式。
建议你拿到手之后,先用Navicat或其他数据库工具把SQL脚本导进去,然后在表关系图里看一眼外键关系。不需要背下来每个字段,但要把订单、用户、商品、商家这四张核心表的关系在脑子里建立起来。后面读源代码的时候,你会反复和这四张表打交道。
2. 把项目跑起来:从解压到下单成功,全流程实录
2.1 环境准备清单:JDK、MySQL、Redis、微信开发者工具,一个都不能少
跑通这套代码需要的工具不算多,但确实是“一个都不能少”。我在实际环境中踩过坑,先列个清单,版本建议基于常见稳定版,能省掉你后面一半的报错排查时间。
| 工具 | 推荐版本 | 用途说明 |
|---|---|---|
| JDK | 1.8或11 | Spring Boot后端运行环境。注意,如果项目用的Spring Boot是2.x,JDK 8完全够用;Spring Boot 3.x则需要JDK 17 |
| Maven | 3.6及以上 | 管理后端Java依赖,下载jar包 |
| MySQL | 5.7或8.0 | 主数据库,存业务数据。建议8.0,性能更好 |
| Redis | 5.x及以上 | 缓存和会话管理,外卖项目里常用来存token或购物车临时数据 |
| 微信开发者工具 | 最新稳定版 | 运行和调试小程序前端 |
| Navicat或DBeaver | 任意 | 可视化操作数据库,执行SQL脚本 |
| Postman或Apifox | 任意 | 调试后端接口 |
这里有几个容易踩的坑。首先JDK版本不匹配是启动失败的头号原因,Spring Boot 2.x用JDK 17会报一些奇怪的反射异常,Spring Boot 3.x用JDK 8则直接起不来。所以建议你先看一眼后端pom.xml里的spring-boot-starter-parent版本号,再决定装哪个JDK。其次MySQL 8.0和5.7在连接驱动上不一样,配置文件里的驱动类和URL参数写法不同,如果项目默认按5.7写,你装8.0就得改application.yml。最后Redis装完之后一定要先启动服务再启动后端,否则项目启动时会因为连接不上Redis直接报错退出。
2.2 后端启动步骤:改三处配置,戳一个坑,后端就起来了
后端启动整体不复杂,但对新手来说每一步都是细节。如果你拿到手的项目数据库脚本是init.sql或schema.sql,建议按下面顺序操作。
**第一步:创建数据库并导入SQL。**用Navicat新建一个数据库,注意字符集选utf8mb4,排序规则选utf8mb4_general_ci或utf8mb4_unicode_ci都行。然后右键选择“运行SQL文件”,把压缩包里sql目录下的文件全部导进去。utf8mb4不是可选项——如果你用了默认的latin1或utf8,商品名称里的emoji或者某些生僻字会直接变成问号。
**第二步:修改application.yml。**重点看三处配置:数据库连接信息的url、username、password;Redis的host和port;端口号配置server.port,默认为8080。这里最常见的坑是MySQL 8.0的驱动类需要加cj前缀,同时URL要带serverTimezone=Asia/Shanghai这样的时区参数,否则启动时会报时区错误。
**第三步:启动后端。**用IDEA打开后端工程,等Maven把依赖下载完(第一次会比较久,国内建议换阿里云镜像),然后运行启动类(类名通常是Application或xxxApplication)。启动过程中不要干别的事,盯着控制台看日志,看到Started Application in x.xx seconds字样才算成功。如果启动失败,最优先看异常栈里第一行Caused by,那才是根因。
我当初跑的时候戳过一个大坑:导入SQL脚本时数据库没选对,结果脚本执行成功但表全建到了别的库里,后端一启动查不到表,所有接口返回“Table doesn't exist”。排查了半天才反应过来,所以建议你在导入之前反复确认当前选中的确实是你新建的数据库。
2.3 前端与小程序端联调:域名校验、不校验合法域名、接口基础路径
后端起来了,接下来就是把小程序前端跑起来。这个环节失败的频率最高,但绝大多数问题都集中在同一个地方——小程序不知道该向哪个地址发请求。
打开微信开发者工具,选择“导入项目”,选中前端目录。导入后第一件事,先找到前端代码里封装请求的文件(通常在utils/request.js或utils/api.js),里面会有一个baseURL常量。这个值的默认写法通常是http://localhost:8080之类,意思是所有接口请求都发到本机的8080端口。你要做的就是确认它和你后端配置的server.port一致。
然后进入微信开发者工具的“详情”菜单,找到“本地设置”,勾选“不校验合法域名、web-view(业务域名)、TLS版本以及HTTPS证书”。这句话翻译成人话就是:本地开发阶段允许小程序请求任意的HTTP接口,而不强制要求必须是HTTPS且备案过的合法域名。正式上线绝对不能勾这个,但本地联调必须勾,很多人半天调不通接口就是因为这个开关没打开。
最后在开发者工具里编译运行,能看到首页的店铺列表说明联调成功。如果页面能打开但数据是空的,打开开发者工具的调试器(Ctrl+Shift+I),切到Network(网络)标签页,看请求有没有发出、返回的状态码是什么。接口联调的本质就是看请求和响应,这条经验适用于所有前后端分离项目,不光是外卖小程序。
2.4 踩坑现场:端口冲突、数据库时区、Redis未启动、request上限
我把自己跑通这套代码过程中遇到的高频问题整理一下,这些问题属于“不遇到不知道,遇到才知道多浪费时间”的典型。
**端口冲突。**Spring Boot默认8080端口,如果你本机的8080被其他程序占了(比如装了别的Java服务、tomcat等),启动会直接报Port already in use。解决方式很简单:改application.yml里的server.port为8081之类,然后把前端baseURL改成对应端口。注意两边必须同步改,很多人在后端改了端口但前端没改,请求全打到旧端口上,白白排查半天。
**MySQL时区报错。**错误信息里出现The server time zone value时,说明你的JDBC连接串里缺了时区参数。在application.yml的数据库URL末尾加上?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8,重启即可。
**Redis连接失败。**后端启动日志里报Unable to connect to Redis,说明Redis服务没起来。Windows下Redis一般需要手动启动,确认一下进程是否在跑。外卖项目里Redis的用途非常多——登录token缓存、验证码存储、热点数据缓存,它挂了整个项目基本没法正常用,所以务必确保它在后端启动之前就在运行。
**请求数据过大。**有些项目的接口默认设置了请求体大小上限,如果你在测试时上传了比较大的图片或批量数据,后端可能会报Maximum upload size exceeded。解决办法是在application.yml里加大spring.servlet.multipart.max-file-size和max-request-size的值。这个坑不是每个人都会遇到,但遇到一次就够你头疼的,提前知道比较好。
3. 仿的只是皮,真正值钱的是这几条业务链路
3.1 用户端:微信登录怎么把openid映射成本地用户
仿美团外卖项目无论怎么仿,用户登录永远绕不开微信登录。我第一次看到这个流程的时候,觉得“不就是wx.login换个code嘛”,但真正理解之后发现,这一整套逻辑才是所有微信电商类小程序的地基。
流程是这样的:小程序前端调用wx.login()拿到一个临时凭证code,把这个code发给后端接口;后端拿着code去调微信官方的接口,换回来两个关键信息——openid(用户在小程序里的唯一ID)和session_key(会话密钥,可以用来解密手机号等敏感数据)。后端拿到openid后,去数据库的user表里查一下这个openid是不是已经存在,不存在就注册一个新用户,存在就直接登录成功,然后后端生成一个自定义的登录态标识(通常是一个token)返回给前端。
为什么不能只靠前端把用户信息传过去?因为openid是微信端算出来的,前端不可信,如果不走后端校验,任何人都可以伪造用户身份。我在测试的时候试过,直接改请求头里的用户ID参数,结果后端返回401 Unauthorized,被拦截了——这才是正确的做法。
token的存储也是门学问。很多项目会把token存在Redis里,设置过期时间,这样用户登录态失效只需要删Redis里的key,不需要改数据库。如果你想做“退出登录”功能,本质就是把这个token从Redis里删掉。理解了这套逻辑,你就能解释很多现象,比如为什么换一台设备重新登录后旧token会失效、为什么token过期后所有接口都返回未登录。
3.2 商家端与配送端:订单状态机如何流转
外卖项目最核心的业务链路是订单。订单状态不是随便一个字段了事,而是一个严格的状态机。理解状态机是读外卖代码的关键。
典型的订单状态流转是这样的:
- 用户提交订单后,状态为
待支付(通常值为0或1); - 用户支付成功后,状态变为
待接单或已支付; - 商家在后台点击“接单”,状态变为
已接单或制作中; - 骑手或商家完成配送后,状态变为
配送中,最后已完成; - 用户主动取消,或者超时未支付系统自动取消,状态变为
已取消。
这个状态机在代码里通常不是散落在接口里随便改的,而是有一个专门的状态流转逻辑。有些项目会在数据库里建一个订单状态记录表,把每一次状态变更都记下来,这样出现纠纷时可以追溯;简单一点的项目则只维护order表里的status字段。
我在这个项目里观察到,几乎所有状态变更都在后端完成,前端只是展示状态。为什么?因为前端的按钮是不可信的,如果让前端直接改状态,用户拿抓包工具改个请求就能把订单改成已完成,那整个系统就废了。所以安全边界是:前端只能发起操作请求,后端校验用户权限后决定是否允许状态变更。
比如说“取消订单”这个按钮,前端点一下,实际是发了一个POST /api/order/cancel的请求,后端先判断这个订单是不是当前用户的,再判断订单状态是不是待支付或待接单,两个条件都满足才真正取消。如果你拿到代码后想加“用户只能在支付后5分钟内取消”这种规则,改的就是后端的这个判断逻辑——加一个时间判断而已。
3.3 购物车与结算:前端算钱还是后端算钱
购物车模块在外卖项目里属于“看起来简单、实现起来全是细节”的部分。先说结论:前端算出来的金额只能用来展示,最终结账金额必须以后端计算为准。
购物车的基本操作是加购、减购、修改数量、删除、清空。前端每操作一次,向后端发请求,后端在Redis或数据库里更新购物车数据。为什么不直接存在前端?因为购物车数据如果只存在本地,用户换个设备购物车就丢了;另外后端需要购物车数据来校验商品的实时库存和价格。
结算时,后端会遍历购物车里的商品,从数据库查出每个商品的实时价格,乘以数量,累加出商品总价,然后加上配送费、减去优惠券金额,得到最终应付金额。为什么要这么做?因为前端展示的价格可能已经过期——比如商家在用户加购后修改了商品价格,如果后端不重新计算,用户就能用旧价格买到商品,商家就得亏本。这个设计原则贯穿所有电商系统:所有和钱有关的计算都必须发生在后端。
具体到代码里,你可能会在后端Service层看到一个calculateTotalAmount之类的方法,它先查购物车,再查商品表,然后逐项计算。顺便说一句,如果你想学“优惠券”功能,看这个方法的扩展空间就知道了——在算完商品总价后加一个优惠券抵扣判断即可,核心数据流完全不用动。
3.4 地图与定位:外卖App最容易被砍掉的功能,源码里是怎么接的
地图和定位是外卖项目里最有辨识度的功能,也是很多“仿品”项目直接砍掉做成固定店铺列表的原因——地图SDK接入麻烦、费用敏感、隐私合规要求高。如果你拿到的代码里保留了地图功能,那这部分绝对值得重点研究。
微信小程序里做地图,通常有两种方案:一是直接用小程序内置的map组件和wx.getLocationAPI,二是接入腾讯地图或高德地图的JavaScript SDK,做逆地址解析(把经纬度转成街道地址)、关键词搜索、POI推荐等。
在仿美团项目里,核心应用场景是这三个:
- 首页根据用户当前位置,按距离从近到远展示店铺列表;
- 店铺详情页展示店铺在地图上的位置;
- 结算页面选择收货地址时,支持地图选点。
距离计算是后端接口常用的功能。后端拿到用户的经纬度和店铺的经纬度,用球面距离公式算出距离,然后按距离排序。真实项目里一般不会直接用非常复杂的算法,用Haversine公式就够了,精度在几米级别,对外卖场景完全足够。如果你在代码里看到类似6371 * acos(...)或者Math.atan2的计算逻辑,那就是算距离的。
这里提醒一个合规问题:微信小程序使用定位能力,需要在app.json里声明permission字段,并且在页面调用wx.getLocation前弹出授权框说明用途。如果你后续想自己开发并上架,这个声明一定要写对,否则审核会被拒。另外,腾讯地图(或高德)的WebService API需要申请开发者账号和Key,个人开发者可以申请免费额度,但是有一定限制。
4. 二次开发升级指南:从“能跑”到“能用”
4.1 加一个“门店列表按距离排序”的小功能,动哪几个文件
跑通项目之后,最有效的学习方式不是读代码,而是改功能。我建议你尝试一个非常贴近外卖业务场景的小需求:在首页门店列表里,把“默认排序”改成“按距离从近到远排序”。这个功能虽然小,但它能让你从数据库到接口再到前端完整走一遍数据流。
操作路径大概是这样的:
- 数据库层:确认
shop表里有没有存经纬度字段。通常会有longitude和latitude两个字段,没有的话你需要加字段并mock数据; - 后端Mapper层:在查询门店列表的SQL里加排序逻辑。MySQL可以用
ORDER BY ACOS(...)实时计算距离排序,但为了性能,更规范的做法是在Service层循环计算距离后按距离排序; - 后端Controller层:确认接口能接收到用户的经纬度参数,把你计算好的距离字段拼进返回结果里;
- 前端页面:调用接口时把
latitude和longitude传上去,然后按返回的distance字段渲染,给用户展示“距离xx米”或者“距离xxkm”。
你会发现,加一个功能需要从前端到后端每一层都动一下,这正好暴露了分层架构的本质——每一层只负责自己该做的事情,改动被隔离在局部。如果前端直接改排序,后端不配合,数据都不完整;如果后端改了但前端不传经纬度,排序也做不了。前后端联调的核心就是“约定接口参数和返回结构”,这个约定一旦打通,功能开发就是填代码的事。
我特别建议再做一个小优化:把首页那些假数据(比如写死的店铺列表)换成从后端接口读出来的真实数据。这一步能帮你彻底理解前后端数据交互的完整链路,比看十遍教程都管用。
4.2 改造建议:如果想把后端换成Node.js或若依,要换什么
有些读者可能对Java不太熟,觉得Spring Boot太“重”,会想“能不能把后端换成Node.js?”。我可以负责任地说:可以,但要做好写大量重复代码的心理准备。
如果你决定用Node.js重写后端,核心不用变的是数据库表结构,要换的是这些:
- 接口层:Spring Boot的
@RestController换成了Express或Koa的路由; - 数据库访问:MyBatis/JPA换成了
mysql2或sequelize; - 缓存:Redis的Java客户端换成
ioredis; - 业务Service层:Java类换成了JavaScript模块,逻辑本身完全一样。
你会发现,技术栈可以换,但业务模型和接口设计不用变。这正是为什么我说读这个项目时,重点是读懂业务流程而不是背Spring Boot的注解——只要业务流程吃透了,换成任何语言都能实现。反过来,如果你只盯着注解看,不思考接口为什么这么设计、状态为什么这么流转,那换个技术栈你就又不会了。
如果想把项目升级到若依框架,思路也是类似的:把商品、订单、用户这三块业务代码抽出来,集成到若依的模块体系里。若依自带代码生成器,可以帮你快速生成单表的CRUD,但复杂的业务逻辑(比如订单状态流转)需要自己动手写。所以我的建议是,先用这个项目把业务吃透,再决定要不要迁移到更重型的管理框架上。
4.3 合规与上线提示:个人主体、审核类目、商用授权
聊到“能用”,就绕不开上线和合规。很多人拿着仿写项目,心里想的是“我能不能自己改一改,真的发布上线?”。这里面的坑和红线,我必须说清楚。
微信小程序上线前要过审核,外卖类小程序属于“电商平台”或“餐饮外卖”类目,个人主体基本过不了。微信要求这类小程序必须由企业主体注册,并且提供对应的行业资质——《食品经营许可证》这类证照是硬门槛。个人开发者想上线外卖平台,基本只能选择“先注册公司”这条路,流程大概需要营业执照、对公账户、食品经营许可证等。如果你是个人开发者,只是想练手或做面试项目,这步完全不用考虑,本地跑通就足够了。
另一个更重要的问题是商用授权。这个压缩包里的项目是“仿美团”,名字和UI都借鉴了美团的设计。这种仿写项目的定位是学习、参考,如果你不加改造、不改名就打包上线,会涉及商标和知识产权纠纷风险。我自己做技术拆解,也一直强调这类项目只能用来学习原理、补充简历、参加面试,不能直接拿来商用。
关于地图服务也提一句:小程序里的地图组件和定位能力,生产环境里用腾讯地图或高德地图需要去对应开放平台申请Key,个人开发者的免费额度有限制。如果你只是本地联调,可以先用测试Key或直接mock数据,避免因为Key的问题卡住开发进度。
5. 避坑手册:基于真实开发中出现频率最高的问题
5.1 接口跨域:为什么前端一直拿不到数据
跨域问题是前后端分离项目的“老朋友”。但这里有个很容易混淆的概念:小程序端其实不存在浏览器跨域问题,因为小程序的请求不是浏览器发的,不受同源策略限制。那为什么你的小程序请求还是“失败”了?大概率是别的原因,比如域名校验没过、baseURL配错,或者后端根本没启动。
真正会遇到跨域问题的场景是:你用H5版调试,或者在小程序里嵌了web-view页面去请求后端接口。这个时候浏览器会拦截跨域请求,后端需要在接口层配置跨域允许。
Spring Boot里最常见的方式有两种:一是用@CrossOrigin注解加在Controller或方法上,二是写一个全局CorsFilter或实现WebMvcConfigurer的addCorsMappings方法。配置的核心就两件事:允许哪些来源、允许哪些请求方法。开发阶段直接允许所有来源(*)就行,生产环境才需要收紧。
我见过很多人在本地联调时被跨域问题卡住,但实际原因根本不是跨域,而是之前提到的域名校验开关没关或者baseURL写错。所以排查思路应该按这个优先级来:先开后端日志看请求有没有到后端,再到小程序Network面板看请求状态码,最后才考虑跨域配置。
5.2 自定义导航栏的适配:iPhone刘海屏与安卓状态栏
外卖小程序的UI设计里,顶部的导航栏往往不是微信默认的,而是根据业务风格定制的。很多仿品项目为了好看都会用自定义导航栏,这里有个隐藏很深的坑——安全区适配。
简单说,iPhone从X系列开始有刘海,安卓也有一堆挖孔屏、水滴屏。自定义导航栏如果高度写死,在iPhone上就可能被刘海遮挡,状态栏时间、电量的位置会被顶到看不见。正确的做法是用微信小程序的API获取系统信息:wx.getSystemInfoSync()里会有statusBarHeight(状态栏高度)和menuButtonCapsule(右上角胶囊按钮位置)。
具体适配逻辑是:导航栏总高度 = 状态栏高度 + 导航栏内容高度(通常是44px)。所以你不能在样式里写死height: 100px,而是要用JS动态计算后通过内联样式或CSS变量设置。我跑通项目后第一件事就是改这个,因为真机预览时发现页面内容被刘海遮住了一大半。
另外,如果项目里用了position: fixed的底部操作栏,同样要注意底部安全区,安卓有导航条,iPhone有Home条。微信给了safe-area-inset-*这个CSS环境变量,直接用env(safe-area-inset-bottom)适配即可。
5.3 分包与包体积:为什么代码一多就白屏
小程序有包大小的限制,主包不能超过2MB(实际上微信现在支持到2MB,用分包可以扩展到20MB)。仿外卖项目功能多,图片多,很容易就超。如果你在开发时发现编译成功后页面白屏、加载特别慢,很可能就是包体积问题。
微信小程序的解决方案是分包加载。把核心页面放在主包里(比如首页、登录、购物车),把低频页面放在分包里(比如订单详情、商家详情、个人中心),只有在用户进入对应页面时才加载对应分包。这个机制对小程序开发者来说特别重要——但前提是你得在app.json里配置好subPackages。
还有一个很容易忽略的优化点:图片是体积大户。开发阶段很多人为了省事直接把设计图或者截图往项目里放,一张图1MB就爆了。建议正式开发时图片都走CDN或对象存储,本地只保留占位图和icon。如果你上手项目后发现包体积超标,先把pages目录和static目录里的大图片找出来压缩一遍,效果立竿见影。
5.4 商家端/骑手端的权限控制:为什么有人能后台改价
外卖系统的权限控制是个大头。用户端、商家端、骑手端、管理后台,不同身份能做的事情完全不同。权限如果做得稀烂,出现的直接后果就是某个用户通过构造请求,把一个订单的价格改了、把一个店铺的营业时间改了等等。
我在这个项目里看到的权限方案相对务实:后端拦截器(Interceptor)统一校验请求头里携带的token,然后从Redis里查出对应的用户信息,判断用户的role(角色)字段是否匹配要求。比如“接单”接口要求role必须是商家管理员,代码里会有一句类似if (!"merchant".equals(user.getRole()))的判断,不满足就返回403。
这个方案虽然简单,但足够应付仿品项目。做权限控制有一个核心原则:后端必须做权限校验,前端隐藏菜单按钮只是用户体验层面的优化,不是安全措施。如果你拿到代码发现前端把管理入口藏在很深的页面里就以为安全了,那就大错特错了——网络请求是透明的,身份伪造也不是什么高端黑客技术,真正能拦住越权的只有后端校验。
另外一个值得关注的是“敏感操作日志”。商家改价格、用户取消订单、管理员修改店铺信息,这些操作建议都记录日志。很多仿品项目没做这一步,但如果你未来要上线,操作日志是监管和纠纷处理的最低保障,属于“能加则加”的功能。
说实话,跑通一个压缩包里的项目,和真正掌握其中的技术,中间隔着的不是代码量,而是你愿不愿意在跑通之后去改它。这份仿美团外卖小程序,学习价值集中在前端的交互细节、小程序与后端的接口约定,以及订单、购物车、用户体系这三条业务链路的实现逻辑上。与其再去找十份新代码看目录,不如把这一份彻底吃透——先跑起来,再加一个功能,最后把它改造成你自己的东西。这些操作流程走完,你对微信小程序项目的理解会从“好像懂了”变成“确实会做”。
本文还有配套的精品资源,点击获取