# 点餐小程序 基于 uni-app 框架开发的微信点餐小程序,使用 Vue 3 + Pinia 构建。 ## 📋 项目简介 这是一个功能完善的微信点餐小程序,提供完整的点餐流程,包括菜品浏览、购物车管理、优惠券使用、订单确认等功能。项目采用现代化的前端技术栈,代码结构清晰,易于维护和扩展。 ### 主要业务场景 - 🍽️ **扫码点餐**: 用户扫描桌码进入点餐页面 - 🛒 **购物车管理**: 实时管理已选菜品,支持增减数量 - 🎫 **优惠券系统**: 优惠券领取和使用 - 📝 **订单确认**: 确认订单信息并提交 - 👤 **个人中心**: 用户信息管理和设置 ## 🛠 技术栈 - **框架**: uni-app - **Vue 版本**: Vue 3 - **状态管理**: Pinia - **构建工具**: HBuilderX / Vite - **主要依赖**: - `@vueuse/core`: Vue Composition API 工具库 - `dayjs`: 日期处理库 - `lodash-es`: JavaScript 工具库 - `uqrcodejs`: 二维码生成库 ## 📁 项目结构 ``` WechatApp/ ├── api/ # API 接口定义 │ ├── index.js # 通用接口 │ ├── dining.js # 点餐相关接口 │ └── login.js # 登录相关接口 ├── components/ # 公共组件 │ ├── Modal/ # 弹窗组件 │ │ ├── BasicModal.vue │ │ └── ScrollPopup.vue │ ├── NavBar/ # 导航栏组件 │ │ ├── index.vue │ │ └── StatusBar.vue │ ├── Share/ # 分享组件 │ │ ├── hook.js │ │ └── ShareBtn.vue │ ├── TabBar.vue # 底部导航栏(首页/扫码点餐/我的) │ └── Upload/ # 文件上传组件 │ ├── index.vue │ └── upload.js ├── hooks/ # 自定义 Hooks │ ├── libs/ # 第三方库 │ │ └── qqmap-wx-jssdk.min.js # 腾讯地图 SDK │ └── usePay.js # 支付相关 Hook ├── pages/ # 页面目录 │ ├── index/ # 首页(菜品展示) │ │ └── index.vue │ ├── numberOfDiners/ # 扫码点餐(选择就餐人数) │ │ └── index.vue │ ├── orderFood/ # 点餐页面 │ │ ├── index.vue │ │ └── components/ # 点餐相关组件 │ │ ├── FoodCard.vue # 菜品卡片 │ │ ├── BottomActionBar.vue # 底部操作栏 │ │ ├── CartModal.vue # 购物车弹窗 │ │ ├── CouponModal.vue # 优惠券弹窗 │ │ └── SelectCouponModal.vue # 选择优惠券弹窗 │ ├── foodDetail/ # 菜品详情页 │ │ └── index.vue │ ├── placeOrder/ # 确认订单页 │ │ └── index.vue │ ├── result/ # 订单结果页 │ │ └── index.vue │ ├── personal/ # 个人中心 │ │ ├── index.vue # 个人中心首页 │ │ ├── userInfo.vue # 个人信息 │ │ └── setPhone.vue # 设置手机号 │ ├── webview/ # WebView 页面 │ │ └── index.vue │ └── components/ # 页面级组件 │ └── LoginModal.vue # 登录弹窗 ├── settings/ # 配置文件 │ ├── enums.js # 枚举常量(存储键名等) │ └── siteSetting.js # 站点配置(API地址、CDN地址等) ├── store/ # 状态管理(Pinia) │ ├── app.js # 应用状态 │ └── user.js # 用户状态(登录、用户信息等) ├── utils/ # 工具函数 │ ├── index.js # 工具函数入口 │ ├── request.js # HTTP 请求封装 │ ├── utils.js # 通用工具函数 │ ├── share.js # 分享工具 │ ├── file.js # 文件处理(CDN地址处理等) │ ├── is.js # 类型判断工具 │ └── uuid.js # UUID 生成 ├── static/ # 静态资源 │ └── img/ # 图片资源 │ ├── tabbar/ # 底部导航图标 │ └── orderFood/ # 点餐相关图片 ├── uni_modules/ # uni-app 插件模块 │ ├── uni-popup/ # 弹窗组件 │ ├── uni-scss/ # 样式工具 │ └── uni-transition/ # 过渡动画 ├── App.vue # 应用入口(全局样式、生命周期) ├── main.js # 主入口文件(应用初始化) ├── initConfig.js # 初始化配置(版本更新检测等) ├── routeInterceptor.js # 路由拦截器(登录验证) ├── pages.json # 页面路由配置 ├── manifest.json # 应用配置文件(AppID、权限等) └── uni.scss # 全局样式变量 ``` ## 🚀 功能特性 ### 核心功能 - ✅ **用户认证**: 微信登录、手机号登录、token 管理、自动登录 - ✅ **路由拦截**: 自动检测登录状态,保护需要登录的页面 - ✅ **请求封装**: 统一的 HTTP 请求处理,自动处理 token、loading、错误提示 - ✅ **状态管理**: 基于 Pinia 的用户状态管理 - ✅ **小程序更新**: 自动检测并提示小程序版本更新 - ✅ **网络检测**: 启动时检测网络状态 ### 业务功能 #### 点餐流程 - 🍽️ **扫码点餐**: 扫描桌码进入点餐流程 - 👥 **选择人数**: 选择就餐人数 - 🍜 **菜品浏览**: 分类浏览菜品,查看菜品详情 - 🛒 **购物车**: 实时管理已选菜品,支持增减数量 - 🎫 **优惠券**: 优惠券领取、选择和使用 - 📝 **订单确认**: 确认订单信息、桌号、人数、优惠等 - ✅ **订单提交**: 提交订单并查看结果 #### 其他功能 - 📱 **首页**: 店铺信息展示、菜品推荐、登录引导 - 👤 **个人中心**: 用户信息管理、手机号设置 - 📤 **文件上传**: 支持图片、文件上传到 OSS - 📍 **地理位置**: 集成腾讯地图 SDK(H5端) - 💰 **支付功能**: 微信支付集成(预留接口) ### UI 组件 - **自定义导航栏**: 支持状态栏适配,自定义样式 - **底部 TabBar**: 三栏导航(首页/扫码点餐/我的),中间为特殊圆形按钮 - **模态弹窗**: 基础弹窗、滚动弹窗组件 - **菜品卡片**: 菜品信息展示,支持加购操作 - **购物车弹窗**: 购物车管理,支持修改数量、清空 - **优惠券弹窗**: 优惠券列表展示和领取 - **登录弹窗**: 快速登录入口 ## 📦 安装与运行 ### 环境要求 - Node.js >= 14.0.0 - HBuilderX 或 支持 uni-app 的 IDE - 微信开发者工具 ### 安装依赖 ```bash # 使用 yarn yarn install # 或使用 npm npm install ``` ### 开发运行 1. 使用 HBuilderX 打开项目 2. 选择运行到微信小程序 3. 或使用命令行: ```bash # 开发环境 npm run dev:mp-weixin # 生产构建 npm run build:mp-weixin ``` ### 配置说明 #### 1. 小程序配置 (`manifest.json`) - **AppID**: `wxc9598c736783dfa9`(当前配置) - **版本号**: `1.0.0` (versionName) / `100` (versionCode) - **权限配置**: - `scope.userLocation`: 位置信息权限 - `scope.record`: 录音权限 - **网络配置**: `urlCheck: false`(开发环境可关闭域名校验) #### 2. API 配置 在 `settings/siteSetting.js` 中配置 API 基础地址: ```javascript // 开发环境 / 生产环境 API 地址 export const BASE_API_URL = process.env.NODE_ENV === 'development' ? 'http://192.168.1.91:8000/aliendining' : 'http://192.168.1.91:8000/aliendining'; // 文件上传地址 export const UPLOAD_URL = 'https://api.xxxxxx.cn/File/UploadImg'; // CDN 地址 export const DEFAULT_CDN_URL = 'https://alien-volume.oss-cn-beijing.aliyuncs.com/'; export const UPLOAD = 'https://alien-volume.oss-cn-beijing.aliyuncs.com/'; ``` #### 3. 腾讯地图配置 在 `manifest.json` 的 `h5.sdkConfigs.maps.qqmap` 中配置地图 Key(仅 H5 端使用): ```json { "h5": { "sdkConfigs": { "maps": { "qqmap": { "key": "" } } } } } ``` #### 4. 页面路由配置 (`pages.json`) 主要页面路由: - `/pages/index/index` - 首页 - `/pages/numberOfDiners/index` - 扫码点餐(选择人数) - `/pages/orderFood/index` - 点餐页面 - `/pages/foodDetail/index` - 菜品详情 - `/pages/placeOrder/index` - 确认订单 - `/pages/result/index` - 订单结果 - `/pages/personal/index` - 个人中心 - `/pages/personal/userInfo` - 个人信息 - `/pages/personal/setPhone` - 设置手机号 - `/pages/webview/index` - WebView 页面 ## 🔧 核心模块说明 ### 路由拦截 (`routeInterceptor.js`) 自动拦截需要登录的页面访问,未登录用户将被引导至登录页,登录成功后自动跳转回原页面。 **拦截的路由方法**: - `uni.navigateTo` - `uni.reLaunch` - `uni.redirectTo` **需要登录的页面列表**(在 `routeInterceptor.js` 中配置) **工作原理**: 1. 检测目标页面是否在登录列表中 2. 检查用户 token 是否存在 3. 未登录时弹出提示,用户确认后跳转登录页 4. 登录成功后从 `REDIRECT_KEY` 读取原目标地址并跳转 ### 请求封装 (`utils/request.js`) 统一的 HTTP 请求处理类,提供以下特性: - ✅ 自动添加 token 到请求头(Authorization) - ✅ 自动显示/隐藏 loading(支持并发请求计数) - ✅ 统一错误处理(根据 code 码处理) - ✅ 请求超时处理(默认 180 秒) - ✅ GET 请求自动添加时间戳防缓存 - ✅ 网络错误提示 **请求配置选项**: ```javascript { url: string, // 请求路径(相对路径) params: object, // 请求参数 headers: object, // 自定义请求头 loading: boolean, // 是否显示 loading(默认 true) timeout: number, // 超时时间(默认 180000ms) returnResponse: boolean, // 是否返回原生响应(默认 false) message: boolean, // 是否显示消息提示(默认 true) hideErrorModal: boolean, // 是否隐藏错误弹窗(默认 false) customizeUrl: string // 自定义完整 URL } ``` **响应码处理**: - `code: 200` - 成功,返回 `data` 字段 - `code: 400` - 系统异常,弹出错误提示 - 其他 code - 根据 `hideErrorModal` 决定是否弹出错误提示 **使用示例**: ```javascript import { api } from '@/utils/request.js'; // GET 请求 const userInfo = await api.get({ url: '/api/user/info', params: { id: 1 } }); // POST 请求 const result = await api.post({ url: '/api/user/update', params: { name: 'test' }, loading: true, // 显示 loading hideErrorModal: false // 显示错误弹窗 }); // 静默请求(不显示 loading 和错误提示) const data = await api.get({ url: '/api/check', loading: false, hideErrorModal: true }); ``` ### 状态管理 (`store/user.js`) 用户状态管理 Store(基于 Pinia),提供以下功能: - ✅ 用户信息管理(内存 + 本地存储) - ✅ Token 管理(自动同步到本地存储) - ✅ OpenId 管理 - ✅ SiteId 管理 - ✅ 登录/登出(带确认提示) - ✅ 自动持久化(使用 `uni.setStorageSync`) **State**: ```javascript { userInfo: null, // 用户信息对象 token: undefined, // 用户 token siteId: undefined, // 站点 ID openId: undefined // 微信 OpenId } ``` **Getters**: - `getUserInfo` - 获取用户信息(优先内存,其次本地存储) - `getToken` - 获取 token - `getOpenId` - 获取 OpenId **Actions**: - `setUserInfo(e)` - 设置用户信息 - `login(e)` - 登录(保存用户信息、token、siteId,显示成功提示) - `beforeLogout()` - 退出前确认 - `logout(option)` - 退出登录(清除存储,可配置是否跳转首页) **使用示例**: ```javascript import { useUserStore } from '@/store/user.js'; const userStore = useUserStore(); // 获取用户信息 const userInfo = userStore.getUserInfo; // 获取 token const token = userStore.getToken; // 登录 userStore.login({ token: 'xxx', siteId: 'xxx', ...userData }); // 退出登录(带确认) userStore.beforeLogout(); // 直接退出(不确认) userStore.logout({ redirct: true }); ``` ### 初始化配置 (`initConfig.js`) 应用启动时的初始化逻辑(在 `App.vue` 的 `onLaunch` 中调用): **功能**: 1. **网络检测**: 检测当前网络状态 - 无网络时提示用户开启网络 - 有网络时继续后续流程 2. **版本更新检测**: 使用 `uni.getUpdateManager()` 检测小程序更新 - 检测到新版本时自动下载 - 下载完成后提示用户重启应用 - 下载失败时提示用户卸载重装 **更新流程**: ``` 启动 → 检测网络 → 检测更新 → 下载更新 → 提示重启 → 应用更新 ``` **注意事项**: - 仅在微信小程序环境执行(`#ifdef MP-WEIXIN`) - 网络检测失败时不会阻止应用启动 ## 🎨 样式规范 项目使用 SCSS,全局样式定义在 `App.vue` 和 `uni.scss` 中。 ### 常用工具类 - `.flex`: Flex 布局 - `.flex-center`: 水平垂直居中 - `.flex-between`: 两端对齐 - `.ellipsis`: 单行省略 - `.ellipsis-2`: 两行省略(支持 2-10 行) - `.safe-area`: 底部安全区适配 ## 📱 页面说明 ### 首页 (`pages/index/index`) - **功能**: 店铺信息展示、菜品推荐、登录引导 - **特性**: - 支持下拉刷新 - 自定义导航栏 - 未登录时显示登录卡片 - 菜品列表展示(图片、名称、价格、月售等) - 菜品加购功能 ### 扫码点餐 (`pages/numberOfDiners/index`) - **功能**: 选择就餐人数 - **入口**: 底部 TabBar 中间圆形按钮 - **流程**: 选择人数 → 进入点餐页面 ### 点餐页面 (`pages/orderFood/index`) - **功能**: 浏览菜品、管理购物车、使用优惠券 - **特性**: - 左侧分类导航 - 右侧菜品列表 - 实时购物车管理 - 优惠券领取和使用 - 底部操作栏(购物车、优惠券、下单) - **组件**: - `FoodCard`: 菜品卡片 - `BottomActionBar`: 底部操作栏 - `CartModal`: 购物车弹窗 - `CouponModal`: 优惠券弹窗 - `SelectCouponModal`: 选择优惠券弹窗 ### 菜品详情 (`pages/foodDetail/index`) - **功能**: 查看菜品详细信息 - **特性**: 自定义导航栏、菜品详情展示 ### 确认订单 (`pages/placeOrder/index`) - **功能**: 确认订单信息并提交 - **内容**: 订单详情、桌号、人数、优惠信息等 ### 订单结果 (`pages/result/index`) - **功能**: 显示订单提交结果 - **状态**: 成功/失败提示 ### 个人中心 (`pages/personal/index`) - **功能**: 用户信息展示、功能入口 - **特性**: 自定义导航栏、用户信息卡片 ### 个人信息 (`pages/personal/userInfo`) - **功能**: 查看和编辑个人信息 ### 设置手机号 (`pages/personal/setPhone`) - **功能**: 设置或修改手机号 ### WebView 页面 (`pages/webview/index`) - **功能**: 内嵌网页展示 - **特性**: 自定义导航栏、支持外部链接加载 ### 登录弹窗 (`pages/components/LoginModal.vue`) - **功能**: 快速登录入口 - **使用**: 在需要登录的页面中调用 ## 🔌 插件说明 ### uni-popup 弹窗组件 uni-app 官方弹窗组件,用于各种弹窗场景。 **安装**: 通过 uni_modules 自动安装 **使用**: ```vue 弹窗内容 ``` ### uni-scss 样式工具 uni-app 官方样式工具库,提供统一的样式变量和工具类。 ### uni-transition 过渡动画 uni-app 官方过渡动画组件,用于页面和组件过渡效果。 ## 📦 依赖说明 ### 核心依赖 - `@dcloudio/uni-ui`: uni-app UI 组件库 - `@vueuse/core`: Vue Composition API 工具库(Vue 3 版本) - `dayjs`: 轻量级日期处理库 - `lodash-es`: JavaScript 工具库(ES 模块版本) - `uqrcodejs`: 二维码生成库 ### 开发依赖 项目使用 HBuilderX 或 Vite 进行构建,具体构建工具根据开发环境而定。 ## 📝 开发规范 ### 代码规范 #### Vue 组件规范 - ✅ 使用 Vue 3 Composition API (`