uni-app 多端餐饮系统源码解析:条件编译与端差异实战
简介这是一套面向中小型餐饮商家的云贝多端餐饮系统源码基于小程序生态打造适用于连锁奶茶店、加盟餐饮店、超市、水果店等需要线上外卖与堂食点单的场景。包内含后台管理、商户端、用户端等完整代码覆盖优惠券、满减、首单立减、分销、积分商城、会员价、直播等营销功能并支持单店/多店切换可帮助开发者或商家快速搭建可运营的餐饮小程序平台。资源共6391个文件以php、js、json、wxml、wxss等前后端源码文件为主同时包含png图片、html页面、mp3音频等素材压缩包大小41.36MB目录结构按后台、商户、前端等模块划分便于定位与二次开发。压缩包内还附有环境配置说明、商户录入、商品分类、DIY装修及独立商户登录权限配置等操作指引能有效缩短上手周期。目前已吸引500人学习下载适合具备一定小程序开发基础、希望获得完整可运行参考实现的开发者参考。1. 小程序云贝多端餐饮系统源码 v2.0.4 在解决什么事小程序云贝多端餐饮系统源码 v2.0.4 完整版这份交付包第一次打开时最容易被“点餐”两个字带偏。它并不只是一套微信小程序界面而是把菜单、购物车、订单、会员和门店信息做成同一套业务代码再分别编译到微信小程序、H5、App 以及部分平台的小程序端。这里说的“多端集合”落在具体开发里就是经常闹矛盾的几个点支付参数不一样、登录态来源不一样、页面安全区不一样、导航栏高度也不一样。对做餐饮 SaaS、接外包或者拿 uniapp 项目练手的开发者来说这套系统的价值是边界清晰购物车、优惠券、订单状态这些通用模块可以当交付基线而真正要花时间的反而是让一份源码在微信开发者工具和 H5 浏览器里表现一致。适合人群是已经会 Vue 基础语法、想在一周内把多端点餐业务跑通的团队。2. 拆多端集合的技术底座uni-app 编译模型与目录约定2.1 为什么这类源码用 uni-app 而不是原生微信小程序先回答一个选型问题餐饮系统多端源码为什么不直接用微信小程序原生语法写原生写法本身没有错但“多端”意味着同一份需求要在微信小程序、H5、iOS、Android 至少四个环境里重复实现。四个端共用后端接口前端却要维护四套页面结构和状态管理这在餐饮这种表单多、联动多的业务里很快就会失控。常见做法是选 uni-app因为它的编译模型把“一次编写”变成了现实。源码里写 Vue 组件编译器根据运行平台把模板和逻辑输出成对应平台的代码同时提供条件编译机制允许你在同一份文件里写“这段只有微信小程序执行那段只有 H5 执行”。!-- #ifdef MP-WEIXIN -- view classpay-btn微信支付/view !-- #endif -- !-- #ifdef H5 -- view classpay-btn跳转收银台/view !-- #endif -- !-- #ifdef APP-PLUS -- view classpay-btn调起 App 支付 SDK/view !-- #endif --上面这段注释不是普通注释uni-app 在编译时会把对应平台不需要的代码块整个剔掉。也就是说支付按钮在微信小程序构建产物里只保留第一段在 H5 产物里只保留第二段。很多初学者以为支付逻辑要写在同一个方法里用 if 判断平台实际多端开发更推荐条件编译因为这样产物体积更小也能避免 App 端代码被错误打包进小程序。当年很多人找“跨平台”解决方案本质就是在找这种编译期裁剪能力。和后来常见的跨平台音乐管理系统 v2.0 源码、小程序商城模板一样uniapp 微信小程序方向几乎成了多端前端事实标准。现在不少 vuegolanguniappai 全栈多端实训营里前端演示项目也是这套模式。2.2 打开 v2.0.4 后最先看的不是 App.vue是 manifest.json 和 pages.json拿到一份多端餐饮系统源码先别急着点运行。我一般会先看根目录结构确认它是不是标准 uni-app 工程。典型的目录长这样cloudbei-dining/ ├── src │ ├── api │ │ ├── request.js │ │ ├── menu.js │ │ └── order.js │ ├── components │ │ ├── menu-item.vue │ │ ├── cart-bar.vue │ │ └── coupon-picker.vue │ ├── pages │ │ ├── index/index.vue │ │ ├── cart/cart.vue │ │ ├── order/confirm.vue │ │ ├── order/list.vue │ │ └── member/member.vue │ ├── store │ ├── static │ ├── utils │ ├── App.vue │ ├── main.js │ ├── manifest.json │ └── pages.json ├── package.json └── vite.config.js这套结构里有两个文件决定了多端行为。第一个是manifest.json它声明应用名称、小程序 AppID、App 模块权限、H5 路由模式第二个是pages.json它只负责页面路由、导航栏样式和 tabBar 配置。在 uni-app 中没有 vue-router页面跳转关系完全由pages.json维护。{ pages: [ { path: pages/index/index, style: { navigationBarTitleText: 点餐首页, enablePullDownRefresh: true } } ], globalStyle: { navigationBarBackgroundColor: #FFB800, navigationBarTextStyle: white }, tabBar: { color: #666666, selectedColor: #FF6B00, list: [ { pagePath: pages/index/index, text: 点餐 }, { pagePath: pages/order/list, text: 订单 }, { pagePath: pages/member/member, text: 我的 } ] } }需要特别注意pages.json里配置的navigationBarTitleText只是默认标题页面运行时经常要按门店名称动态设置标题这时候不能去改pages.json而要在页面里调用uni.setNavigationBarTitle({ title: shopName })。这个动作和 Vue 路由的 meta 思路类似但执行入口完全不同。2.3 “多端集合”的端边界划分多端项目常说支持“多端”但其实各端的环境差异可以整理成下面这张表。理解这张表再去做条件编译分支时就不会漏。端标识典型运行环境编译目标最容易踩的差异MP-WEIXIN微信开发者工具、真机微信小程序原生页面导航栏返回层级只有 10 层H5浏览器、微信公众号内部浏览器标准 Web 资源存在跨域限制需要后端开放 CORSAPP-PLUSiOS、Android WebViewjsbundle 或原生安装包支付、分享、登录都依赖原生 SDKMP-ALIPAY支付宝小程序支付宝小程序代码api 名称差异部分组件样式不同在多端源码里uni.getSystemInfoSync()会返回uniPlatform字段它的值是上面表格左侧的标识。不同端的差异一部分靠编译期条件注释处理另一部分靠运行期分支处理。const platform uni.getSystemInfoSync().uniPlatform if (platform MP-WEIXIN) { // 微信小程序环境逻辑 } else if (platform H5) { // H5 环境逻辑 }原则是能用条件编译解决的尽量用条件编译因为它不会把多余的端代码打进产物只有涉及运行时环境探测才用uniPlatform判断比如动态决定登录页面跳转方式、请求域名是否追加参数。3. 把 v2.0.4 源码跑起来从 HBuilderX 到微信开发者工具的闭环3.1 先判断工程形态再选启动方式多端源码交付形态有两种一种是纯 CLI 工程另一种是 HBuilderX 导入工程。拿到压缩包后先找根目录有没有package.json有就走命令行工具流没有的话大概率是 HBuilderX 内置工程直接拖入 HBuilderX 运行。CLI 方式对后端开发更友好全部用 npm 脚本管理。在项目根目录执行npm install npm run dev:mp-weixindev:mp-weixin的产物默认输出到dist/dev/mp-weixin目录。这里要注意微信开发者工具导入项目时不能导入整个仓库根目录要选到dist/dev/mp-weixin这一层否则开发者工具会找不到 app.json。如果用的是 HBuilderX操作路径是文件 - 导入 - 从本地目录导入然后打开manifest.json在基础配置里换成自己的微信小程序 AppID再点击运行 - 运行到小程序模拟器 - 微信开发者工具。HBuilderX 会自动把源码编译并唤起微信开发者工具。两种方式没有绝对好坏。CLI 工程可以稳定使用 Git 版本管理、GitHub CI 和 eslintHBuilderX 内置工程对新手更直观但依赖 IDE 版本。v2.0.4 这类带“完整版”字样的源码转 CLI 前先看package.json里 Vue 版本Vue 2 工程对应 webpack 编译器Vue 3 工程对应 Vite 编译器安装依赖时混用包管理器容易出问题。3.2 要跑通接口请求改 baseURL、处理跨域、统一错误码多端前端源码里网络请求层几乎都收敛在一个request.js文件里。这个文件的作用不只是封装uni.request它还要把登录态 token、错误提示、业务码判断全部集中处理。// src/api/request.js const BASE_URL { development: http://localhost:8080/api, production: https://api.example.com/api }[process.env.NODE_ENV] export function request(options) { return new Promise((resolve, reject) { uni.request({ url: BASE_URL options.url, method: options.method || GET, data: options.data || {}, header: { token: uni.getStorageSync(token), Content-Type: application/json }, timeout: 10000, success(res) { const body res.data if (body.code 0) { resolve(body.data) } else if (body.code 401) { uni.removeStorageSync(token) uni.navigateTo({ url: /pages/member/login }) } else { uni.showToast({ title: body.msg || 请求失败, icon: none }) reject(body) } }, fail(err) { uni.showToast({ title: 网络异常, icon: none }) reject(err) } }) }) }这段封装里有两个对餐饮系统特别重要的参数。第一个是timeout: 10000点餐场景里用户经常在弱网环境扫码超时不能设太短至少 8 到 10 秒第二个是header.token小程序端登录后一般把 token 放 storage密码错误或会话过期后由后端返回code: 401前端统一清掉 token 并跳登录页。H5 端调试会碰到另一个问题前端代码运行在http://localhost:5173后端接口跑在http://localhost:8080两者端口不同浏览器默认拦截跨域请求。CLI 工程可以在vite.config.js里配置转发import { defineConfig } from vite import uni from dcloudio/vite-plugin-uni export default defineConfig({ plugins: [uni()], server: { proxy: { /api: { target: http://localhost:8080, changeOrigin: true } } } })配置后request.js里的开发地址可以直接写成/api由 dev server 转发到目标地址。但这条只在本地开发时有效生产环境建议在 Nginx 层面配置同源转发否则 H5 还是要面对跨域 preflight 请求。3.3 用条件编译隔离登录、支付和上传餐饮系统的端差异基本集中在三类能力支付、登录、图片上传。微信小程序登录需要先调用wx.login获取 code再拿 code 换 openidH5 端则更习惯用手机号验证码或者账号密码App 端还要判断是否安装了微信客户端。// 登录入口示例 async function login() { const platform uni.getSystemInfoSync().uniPlatform if (platform MP-WEIXIN) { const { code } await uni.login() return request({ url: /auth/wx-login, method: POST, data: { code } }) } return request({ url: /auth/password-login, method: POST, data: { username, password } }) }如果这套源码里把登录和支付写死成同一个流程建议先改成上述结构。后端接口一般是同时支持多种登录方式的前端只需要按平台选择对应url。同理图片上传在微信小程序里用uni.chooseImage和uni.uploadFileH5 端也兼容这两套 API但 App 端可能要区分相册权限和拍摄权限权限拒绝时的错误提示要单独处理。3.4 小程序备案备注信息怎么填微信小程序上线前会要求填写“小程序备案”信息这里经常有提交被驳回的情况。类目选择要注意多端餐饮系统如果只做堂食点餐类目一般落在“餐饮-点餐”、外卖类目下如果包含商城和会员储值备注里要把这些功能写具体。服务内容标识选完后备注栏不要写“软件开发”或“小程序开发”这类空泛描述。审核人员会拿备注和线上版本对照建议写成“提供菜品浏览、扫码点餐、在线预点单、会员储值、外卖订单查询等功能”。如果源码里只实现了堂食扫码点单把“外卖”写进去反而会触发资质审核所以要先看 v2.0.4 里实际编译出来的页面有哪些 tabs再如实填写。4. 多端餐饮业务落地菜单、购物车、支付和定位4.1 菜单列表和购物车联动数据模型先行多端餐饮系统的首页一般由左侧分类、右侧菜品列表、底部购物车栏构成。这个页面逻辑在所有端都通用真正影响多端体验的是数据模型。菜品图片地址、价格、库存、分类 ID 这些字段结构大致如下template view classmenu-item click$emit(select, item) image :srcitem.image modeaspectFill classitem-image / view classitem-info text classitem-name{{ item.name }}/text text classitem-remark{{ item.description }}/text view classitem-price text classprice-symbol¥/text text classprice-value{{ item.salePrice }}/text /view /view /view /template script setup defineProps({ item: { type: Object, required: true } }) /script style scoped .menu-item { display: flex; padding: 24rpx 20rpx; border-bottom: 1rpx solid #f0f0f0; } .item-price { color: #ff6b00; font-weight: 600; } /style购物车状态不要散落在每个页面组件里而应该放进store统一管理。每次加菜操作触发的不是页面跳转而是把菜品对象写入购物车 store再通过 computed 计算总价。这样在不同端之间切换时购物车数据不会因为页面销毁而丢失。小程序端购物车数据还要做本地持久化用uni.setStorageSync(cart, cartList)否则用户退出再进入时需要重新加菜。4.2 支付uni.requestPayment 在不同端的不同入参支付是多端餐饮系统源码里最容易出错的部分主要问题不在地图、菜单而在支付参数结构。微信小程序支付要求后端返回timeStamp、nonceStr、package、signType、paySign五个字段App 端微信支付却经常只需要后端返回一个orderInfo字符串H5 微信支付又要走WeixinJSBridge或跳转链接。常规调起支付写法如下const platform uni.getSystemInfoSync().uniPlatform const paymentParams { MP-WEIXIN: { provider: wxpay, timeStamp: order.timeStamp, nonceStr: order.nonceStr, package: order.packageValue, signType: MD5, paySign: order.paySign }, APP-PLUS: { provider: wxpay, orderInfo: order.orderInfo } } uni.requestPayment({ ...paymentParams[platform], success() { uni.showToast({ title: 支付成功, icon: success }) }, fail(err) { uni.showToast({ title: 支付取消或失败, icon: none }) } })注意package是 JavaScript 保留字段在对象里使用package作为 key 是可以的但很多后端接口把它命名为packageValue或orderStr。代码里的order对象来自前端调起支付接口的返回值这个接口必须由服务端签名前端不能参与任何签名逻辑。微信开发者工具里可以打开“模拟支付”来完成 UI 联调但完整支付链路必须在真机上用真实订单验证。4.3 天地图在移动端 uniapp 里能不能用门店定位是餐饮系统绕不开的模块有人问“天地图移动端 uniapp 能用吗”。结论是可以用但不能像腾讯地图那样直接替换map组件底图。uni-app 内置的map组件在微信小程序端对应腾讯地图在 H5 端对应浏览器地图 API它本身不带天地图瓦片层。如果门店系统坚持用天地图常见做法是通过web-view组件嵌入天地图 JS API 页面uniapp 与 web-view 之间用uni.postMessage传递门店经纬度和点击事件。但这种方案在微信小程序内有域名限制体验不如原生map流畅。对大多数餐饮点餐场景更合理的选型是保留map组件只把getLocation权限和导航功能做好。uni.getLocation({ type: gcj02, success(res) { const { latitude, longitude } res // 将坐标传给后端做门店距离排序 request({ url: /shop/nearby, data: { latitude, longitude } }) }, fail(err) { if (err.errMsg err.errMsg.indexOf(auth deny) -1) { uni.showModal({ title: 需要定位权限, content: 请在设置中开启定位 }) } } })调用getLocation之前需要在manifest.json对应平台模块里勾选定位权限。微信小程序端还要在permission字段里声明scope.userLocation的用途否则用户首次进入时不会弹授权框。4.4 App 端拉起微信小程序的多端跳转多端集合里有一类需求是 App 端引导用户进微信小程序领优惠券这是 “uniapp 从 app 端拉起微信小程序” 的标准场景。App 端通过uni.navigateToMiniProgram可以跳到关联的微信小程序。uni.navigateToMiniProgram({ appId: wx1234567890abcdef, path: pages/coupon/index?shopId1001, success(res) { // 跳转成功 }, fail(err) { uni.showToast({ title: 未安装微信或跳转失败, icon: none }) } })这个接口限制比较多App 端和微信小程序必须关联到同一个微信开放平台账号App 端需要安装微信客户端。条件编译在这里也适用只有APP-PLUS才执行navigateToMiniProgramH5 端应改为展示提示用户复制小程序信息。5. 发版前用条件编译裁剪一份“端差异清单”多端源码最怕的不是写错业务逻辑而是“某个端漏改了差异点”。这里分享一个我常用的做法在发版前把 three 类差异单独列成检查清单然后按顺序跑三个构建命令。scripts: { build:mp-weixin: uni build -p mp-weixin, build:h5: uni build, build:app: uni build -p app }先把build:mp-weixin产出的dist/build/mp-weixin导入微信开发者工具用“预览”生成二维码真机上走一遍从首页加菜到提交订单的完整流程。再切到 H5用浏览器 devtools 的移动模拟窗口调出 Network 面板重点看登录、菜单、下单三个请求是否按预期顺序出现。检查清单可以精简成下面几项检查点微信小程序H5App登录来源微信授权 code账号密码或验证码微信 App 拉起支付调起uni.requestPayment五参数跳转收银台或 JSAPIorderInfo调起 SDK图片上传相册授权浏览器 file 选择相册、相机权限分离底部安全区微信 tabBar 自带需要计算env(safe-area-inset-bottom)原生导航栏一般无此问题请求域名需要配置 request 合法域名需要 CORS 支持支持任意 https 域名除了清单还要处理微信小程序页面栈的限制。小程序端uni.navigateTo最多只能打开十层页面App 端不限制。用户从首页点进菜品详情再进购物车再进确认订单连续跳四级后返回直接用uni.navigateBack没问题但如果中间出现了扫码进入商详页、从商详页调起收银台的场景就要在跳转前判断页面栈深度深度超过阈值时改用uni.redirectTo替换当前页避免页面栈堆满。安卓真机上还要注意明文流量问题。后端接口如果不是 https而是http://Android 9 以后默认拦掉明文请求。解决方式是后端切换 https或者临时在 Android 工程里配置networkSecurityConfig但临时配置只适合本地联调不要让测试包携带这个配置提交到应用市场。把这轮检查代码保存成一个发版 commit下次再从 v2.0.4 基线二次开发时直接照这个清单就能把端差异收敛得快很多。本文还有配套的精品资源点击获取
上一篇/下一篇内容由系统自动关联
返回资讯列表 →