简介:这份资源是面向微信小程序开发初学者与电商系统学习者的在线点餐商城源码,基于微信小程序开发框架并结合Java后端服务,提供了一套完整的餐饮点餐解决方案。包内共60个文件,以10个js逻辑文件、8个json配置、8个wxss样式、7个wxml页面结构为主,另含16张jpg与10张png界面素材及1个md说明文档,压缩包约1.18MB,目录涵盖页面组件、工具函数与全局配置等模块。目前已有1148人学习下载。通过研读这套源码,读者可掌握WXML与WXSS构建菜品展示、购物车、订单确认等界面的方法,理解JavaScript处理用户交互、网络请求与数据更新的业务逻辑,并学习后端接口设计、数据库结构以及微信支付SDK对接流程。资源还涉及云开发与RESTful接口设计思路,适合新手对照实践,快速理解小程序点餐系统的整体运作机制与开发技术栈。
1. 从一份 Java 后端 + 小程序前端的点餐源码说起
打开这份weapp-store-master压缩包,第一眼看到的目录结构其实很朴素:app.js、app.json、app.wxss三个全局文件,加上page、utils、imgs三个目录,再配一份README.md。没有花哨的脚手架,也没有 npm 依赖树,就是一套能直接拖进微信开发者工具跑起来的原生小程序点餐前端。它解决的是餐饮场景里最典型的一条链路:顾客扫码进店 → 浏览菜品 → 加购物车 → 下单 → 走微信支付 → 后端出单。适合两类人:一类是想拿一个真实项目练手小程序开发的新手,另一类是手里有 Java 后端、缺一套现成点餐前端的从业者。源码本身是前端壳子,真正的业务闭环要靠你自己接后端接口,这一点先讲清楚,后面所有章节都围绕「怎么把它跑起来、怎么接后端、哪里会翻车」展开。
2. 拆开 weapp-store-master:目录结构与运行机制
2.1 全局三件套到底管什么
小程序和普通网页最大的区别在于「配置驱动」。app.json是小程序的全局配置,页面路径、窗口表现、tabBar、网络超时都在这里声明;app.js是应用级逻辑入口,负责onLaunch生命周期、全局数据挂载、登录态初始化;app.wxss是全局样式表,相当于网页里的 reset + 公共类。三者缺一,项目在开发者工具里直接报错起不来。
先看app.json的典型结构,这份点餐源码里它大致长这样:
{ "pages": [ "page/index/index", "page/menu/menu", "page/cart/cart", "page/order/order", "page/my/my" ], "window": { "navigationBarTitleText": "在线点餐", "navigationBarBackgroundColor": "#ffffff", "navigationBarTextStyle": "black" }, "tabBar": { "list": [ { "pagePath": "page/index/index", "text": "首页" }, { "pagePath": "page/menu/menu", "text": "点餐" }, { "pagePath": "page/cart/cart", "text": "购物车" }, { "pagePath": "page/my/my", "text": "我的" } ] }, "networkTimeout": { "request": 10000 } }pages数组的第一项就是小程序启动后的默认首页,顺序不能乱;tabBar.list里的pagePath必须和pages中已注册的路径完全一致,少一个斜杠都会导致 tab 不显示。networkTimeout.request设成 10000 毫秒是常见做法,点餐场景下菜品列表接口偶尔慢,给 10 秒比默认的 60 秒更容易暴露后端问题。
app.js里通常挂着全局登录逻辑:
App({ globalData: { userInfo: null, token: '', baseUrl: 'https://your-domain.com/api' }, onLaunch() { // 启动时检查本地缓存里的登录态 const token = wx.getStorageSync('token'); if (token) { this.globalData.token = token; } } })globalData.baseUrl是后面所有网络请求的根地址,改成你自己的后端域名即可。onLaunch只执行一次,适合做登录态恢复,不适合放页面级的数据请求——这是新手最容易搞混的地方,页面数据要在onLoad里拿。
2.2 page 目录下的页面组织逻辑
page目录是业务主战场,每个页面一个文件夹,里面固定四个文件:.wxml结构、.wxss样式、.js逻辑、.json页面配置。点餐系统的页面通常拆成首页、菜单、购物车、订单、个人中心五块。菜单页是核心,它要处理分类切换、菜品渲染、加购动画;购物车页要处理数量增减、总价计算、选中状态;订单页要处理提交和支付回调。
以菜单页的加购逻辑为例,常见写法是这样:
Page({ data: { categories: [], currentCategory: 0, dishes: [], cart: {} }, onLoad() { this.fetchMenu(); }, fetchMenu() { const { baseUrl } = getApp().globalData; wx.request({ url: `${baseUrl}/menu/list`, method: 'GET', success: (res) => { if (res.data.code === 200) { this.setData({ categories: res.data.data.categories, dishes: res.data.data.dishes }); } }, fail: () => { wx.showToast({ title: '菜单加载失败', icon: 'none' }); } }); }, addToCart(e) { const dishId = e.currentTarget.dataset.id; const cart = { ...this.data.cart }; cart[dishId] = (cart[dishId] || 0) + 1; this.setData({ cart }); wx.setStorageSync('cart', cart); } })fetchMenu用wx.request拉后端菜单数据,res.data.code === 200是约定俗成的业务状态码判断,别只看 HTTP 状态码。addToCart用对象存购物车,key 是菜品 ID,value 是数量,这种结构比数组好做增减和去重。每次加购同步写一次wx.setStorageSync,防止用户切后台丢数据。参数上e.currentTarget.dataset.id对应 WXML 里的>const request = (url, method = 'GET', data = {}) => { const { baseUrl, token } = getApp().globalData; return new Promise((resolve, reject) => { wx.request({ url: baseUrl + url, method, data, header: { 'Authorization': token ? `Bearer ${token}` : '' }, success: (res) => { if (res.data.code === 200) resolve(res.data.data); else reject(res.data); }, fail: reject }); }); }; module.exports = { request };
header里带Authorization是接 Java 后端时的通用做法,后端用 JWT 或 Session 校验都认这个头。imgs目录就是静态图片,菜品占位图、图标、tabBar 图标都放这,注意小程序对本地图片有体积限制,别塞大图。
3. 接上 Java 后端:接口约定与联调步骤
3.1 前后端接口的字段约定
这份源码前端是现成的,后端要你自己搭或对接。Java 后端用 Spring Boot 是主流选择,接口返回结构建议统一成{ code, msg, data }三段式,前端utils/request.js里就是按这个结构解析的。如果后端返回的是{ success, result }这种,你得改前端封装,否则每个页面都要单独适配,维护成本翻倍。
点餐系统最少需要这几组接口:
| 接口路径 | 方法 | 作用 | 关键参数 |
|---|---|---|---|
| /api/menu/list | GET | 拉菜单分类和菜品 | 无 |
| /api/cart/sync | POST | 同步购物车 | cart 对象 |
| /api/order/create | POST | 创建订单 | 菜品列表、桌号 |
| /api/order/pay | POST | 发起支付 | orderId |
| /api/user/login | POST | 登录换 token | code |
/api/user/login的code是小程序wx.login()拿到的临时凭证,后端拿它去换openid和session_key,再签发自己的 token 返给前端。这一步是微信登录的标准流程,别想着前端直接存 openid,不安全也不合规。
3.2 本地联调的具体操作
第一步,在微信开发者工具里打开项目,右上角「详情」→「本地设置」,勾选「不校验合法域名」。开发阶段后端跑在localhost:8080,不勾这个选项请求会被拦。
第二步,把app.js里的baseUrl改成http://localhost:8080/api,注意别带尾斜杠,否则拼接出来是双斜杠。
第三步,启动 Java 后端。Spring Boot 项目常见启动命令:
# 打包后运行 mvn clean package -DskipTests java -jar target/order-server-0.0.1-SNAPSHOT.jar # 或者开发模式直接跑 mvn spring-boot:run-DskipTests是跳过测试加速打包,本地联调够用。启动后看控制台有没有Started Application in x seconds,有就说明端口起来了。
第四步,在开发者工具里点「编译」,看 Network 面板的请求。如果菜单页空白,先看请求有没有发出去,再看返回的code是不是 200。常见情况是后端跨域没配,Spring Boot 加个@CrossOrigin或全局 CORS 配置即可。
3.3 微信支付接入的边界
支付是小程序点餐里最容易翻车的一环。前端调wx.requestPayment,需要后端先调微信统一下单接口拿到prepay_id,再签名返回给前端。前端代码大致是:
wx.requestPayment({ timeStamp: res.timeStamp, nonceStr: res.nonceStr, package: res.package, signType: 'RSA', paySign: res.paySign, success: () => { /* 支付成功,跳订单页 */ }, fail: (err) => { /* 用户取消或签名错误 */ } })signType现在推荐RSA,老项目里还有MD5,对接前先确认后端用的哪种,签名算法不一致会一直报「支付验证签名失败」。另外支付功能需要企业主体的小程序账号,个人号调不起来,这是硬门槛,别在开发阶段卡太久。
4. 避坑与排查:点餐源码跑不起来的五个真实原因
4.1 页面白屏,控制台报「Page is not constructed」
现象是编译通过但页面一片空白,控制台提示某个 page 未构造。原因通常是app.json的pages里注册了路径,但对应文件夹下缺.js或.json文件,小程序要求四件套齐全。解决方法是逐个核对pages数组和实际目录,缺哪个补哪个,.json哪怕只写一个{}也要有。
4.2 请求全部 404,但浏览器能访问后端
现象是wx.request返回 404,可你把同样的 URL 贴浏览器里能出数据。原因是开发者工具没勾「不校验合法域名」,或者baseUrl拼接多了斜杠。解决方法是先勾选不校验,再检查baseUrl末尾和接口路径开头是否重复带/,拼出来变成//api/menu/list就会 404。
4.3 购物车数量加了但总价不变
现象是点加购按钮,数量变了,底部总价纹丝不动。原因是总价是在setData之后单独算的,但算的时候读的还是旧cart。解决方法是把总价计算放进同一个setData之前,或者用this.data.cart重新遍历求和,别依赖异步更新后的值。小程序setData是异步的,这个坑新手必踩。
4.4 真机预览图片不显示,模拟器正常
现象是开发者工具里菜品图好好的,扫码真机预览全裂。原因是imgs里用了本地绝对路径或中文文件名,真机对路径大小写和编码更敏感。解决方法是图片统一放imgs下用英文小写命名,引用时用相对路径/imgs/dish.png,别用../../往上跳。
4.5 支付调起就报「商户号不存在」
现象是wx.requestPayment直接 fail,提示商户号相关错误。原因是后端统一下单时用的mch_id和小程序绑定的商户号不一致,或者根本没在微信商户平台完成绑定。解决方法是登录商户平台确认小程序 appid 和商户号已关联,再核对后端配置里的mch_id、apiKey是否和商户平台一致。这个错误前端改不了,必须后端和商户后台一起查。
5. 二次开发与验证:把源码改成你自己的点餐系统
拿到源码只是起点,真正要用起来得做几处改造。第一处是换baseUrl和接口字段,把utils/request.js里的解析逻辑对齐你的 Java 后端返回结构,如果后端返回{ status, data },就改判断条件,别硬套code === 200。第二处是加桌号或门店标识,点餐系统通常要区分桌台,在app.js的globalData里加一个tableId,下单接口带上它,后端才能知道是哪桌的订单。
第三处是缓存策略。小程序wx.setStorageSync默认永久存储,购物车数据放久了会脏。常见做法是给缓存加时间戳:
const CACHE_TTL = 2 * 60 * 60 * 1000; // 2小时 function setCache(key, value) { wx.setStorageSync(key, { value, expire: Date.now() + CACHE_TTL }); } function getCache(key) { const cache = wx.getStorageSync(key); if (!cache) return null; if (Date.now() > cache.expire) { wx.removeStorageSync(key); return null; } return cache.value; }CACHE_TTL设 2 小时是因为一顿饭的用餐时长基本在这个范围内,超时自动清掉,避免第二天打开还挂着昨天的购物车。这个封装替换掉源码里裸的setStorageSync即可,改动量很小。
验证改造是否成功,我一般走一遍完整链路:清缓存 → 进菜单页看接口是否返回 → 加三个菜 → 进购物车改数量 → 提交订单 → 看后端日志有没有收到 → 支付环节用沙箱或测试商户号跑通。每一步都在开发者工具 Network 面板留痕,哪一步断了就查哪一步的请求和响应。
最后说个习惯。我每次拿到别人的小程序源码,第一件事不是急着改业务,而是先把app.json的pages和实际目录对一遍,再把baseUrl和请求封装读一遍,这两处通了,项目基本就能跑。从那以后我每次接新源码都强制走一遍这个检查,省下的排查时间比写业务还多。希望帮到你。
本文还有配套的精品资源,点击获取