温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片!
1. 项目背景与意义
随着移动互联网的普及和微信生态的持续完善,微信小程序已成为餐饮行业数字化升级的重要入口。对于烧烤店这类高频、即时性强的餐饮业态而言,顾客往往希望在到店前完成点餐、预约或外卖下单,以减少排队等待时间,提升用餐体验。
传统烧烤店普遍存在以下痛点:
- 点餐效率低:高峰期服务员不足,顾客等待时间长,容易造成流失。
- 菜单更新滞后:纸质菜单无法实时反映菜品售罄、价格调整等信息。
- 订单管理混乱:手工记录订单易出错,后厨与前台沟通成本高。
- 缺乏用户沉淀:缺少会员体系和消费数据分析,难以进行精准营销。
因此,设计并实现一个基于微信小程序的烧烤店订餐系统,具有以下意义:
- 提升运营效率:顾客自助下单,减少人工干预,降低出错率。
- 优化用户体验:随时随地浏览菜单、下单支付,减少等待时间。
- 数据驱动经营:通过订单数据和用户行为分析,辅助菜品调整和营销决策。
- 降低开发成本:微信小程序无需下载安装,依托微信生态即可触达海量用户。
2. 系统需求分析
2.1 功能需求
本系统面向三类角色:顾客、商家管理员和系统管理员,核心功能模块如下:
| 角色 | 功能模块 | 说明 |
|---|---|---|
| 顾客 | 用户登录注册 | 微信授权一键登录,绑定手机号 |
| 顾客 | 菜品浏览 | 按分类查看菜品、价格、图片、销量 |
| 顾客 | 购物车管理 | 添加、删除、修改菜品数量 |
| 顾客 | 订单管理 | 提交订单、在线支付、查看订单状态 |
| 顾客 | 个人中心 | 查看历史订单、收藏菜品、意见反馈 |
| 商家 | 菜品管理 | 上架、下架、修改菜品信息 |
| 商家 | 订单处理 | 接单、制作、出餐、完成订单 |
| 商家 | 数据统计 | 查看日/周/月销售额、热门菜品排行 |
| 管理员 | 用户管理 | 审核商家、管理用户状态 |
| 管理员 | 系统配置 | 轮播图、公告、分类管理等 |
2.2 非功能需求
- 性能:页面首屏加载时间不超过 3 秒,接口响应时间不超过 500 毫秒。
- 安全:用户密码加密存储,接口鉴权使用 Token 机制,防止 SQL 注入和 XSS 攻击。
- 可用性:系统支持高并发访问,高峰期订单不丢失、不重复。
- 可维护性:前后端分离,代码结构清晰,便于后续功能扩展。
3. 系统技术栈
3.1 前端技术栈
| 技术 | 说明 |
|---|---|
| 微信小程序原生框架 | WXML、WXSS、JS、JSON 四件套,生态成熟、文档完善 |
| Vant Weapp | 基于 Vue 的移动端组件库,提供按钮、弹窗、表单等 UI 组件 |
| ECharts | 用于商家端数据统计图表的可视化展示 |
| 微信支付 API | 实现用户在线下单支付功能 |
3.2 后端技术栈
| 技术 | 说明 |
|---|---|
| Spring Boot | Java 后端框架,快速构建 RESTful API |
| MyBatis-Plus | ORM 框架,简化数据库操作,内置分页插件 |
| MySQL | 关系型数据库,存储用户、菜品、订单等核心数据 |
| Redis | 缓存热点数据(如菜品列表、购物车),提升并发性能 |
| JWT | 无状态身份认证,保障接口安全 |
| Maven | 项目构建和依赖管理工具 |
3.3 系统架构图
flowchart TD A[微信小程序客户端] -->|HTTPS 请求| B[Nginx 反向代理] B --> C[Spring Boot 后端服务] C --> D[MySQL 数据库] C --> E[Redis 缓存] C --> F[微信支付 API] C --> G[微信登录 API] A -->|登录凭证| G4. 数据库设计
系统核心数据表包括用户表、菜品表、订单表、订单明细表、购物车表和分类表。以下为主要表结构设计。
4.1 用户表(user)
| 字段名 | 类型 | 说明 |
|---|---|---|
| id | bigint | 主键,自增 |
| openid | varchar(64) | 微信用户唯一标识 |
| nickname | varchar(50) | 用户昵称 |
| avatar | varchar(255) | 用户头像 URL |
| phone | varchar(20) | 手机号 |
| role | tinyint | 角色:0 顾客,1 商家,2 管理员 |
| create_time | datetime | 注册时间 |
4.2 菜品表(dish)
| 字段名 | 类型 | 说明 |
|---|---|---|
| id | bigint | 主键,自增 |
| category_id | bigint | 所属分类 ID |
| name | varchar(100) | 菜品名称 |
| price | decimal(10,2) | 单价 |
| image | varchar(255) | 菜品图片 URL |
| description | varchar(500) | 菜品描述 |
| sales | int | 销量 |
| status | tinyint | 状态:1 上架,0 下架 |
4.3 订单表(orders)
| 字段名 | 类型 | 说明 |
|---|---|---|
| id | bigint | 主键,自增 |
| order_no | varchar(32) | 订单编号 |
| user_id | bigint | 下单用户 ID |
| total_amount | decimal(10,2) | 订单总金额 |
| status | tinyint | 状态:0 待支付,1 已支付,2 制作中,3 已完成,4 已取消 |
| remark | varchar(255) | 备注信息 |
| create_time | datetime | 下单时间 |
5. 核心功能实现
5.1 微信登录
用户首次进入小程序时,前端调用wx.login获取临时凭证 code,后端通过该 code 向微信接口换取 openid,并生成 JWT Token 返回给前端。
@RestController @RequestMapping("/api/user") public class UserController { @Autowired private UserService userService; @PostMapping("/login") public Result login(@RequestBody LoginDTO dto) { // 调用微信接口换取 openid String openid = userService.getOpenId(dto.getCode()); // 查询或创建用户 User user = userService.findOrCreate(openid); // 生成 JWT Token String token = JwtUtil.generateToken(user.getId(), user.getRole()); return Result.success(token); } }5.2 菜品列表查询
首页菜品列表按分类展示,后端使用 MyBatis-Plus 分页查询,并将热点数据缓存到 Redis,降低数据库压力。
@Service public class DishServiceImpl implements DishService { @Autowired private DishMapper dishMapper; @Autowired private RedisTemplate<String, Object> redisTemplate; @Override public PageResult<Dish> listByCategory(Long categoryId, int page, int size) { String key = "dish:category:" + categoryId + ":" + page + ":" + size; PageResult<Dish> cached = (PageResult<Dish>) redisTemplate.opsForValue().get(key); if (cached != null) { return cached; } Page<Dish> pageInfo = new Page<>(page, size); LambdaQueryWrapper<Dish> wrapper = new LambdaQueryWrapper<>() .eq(Dish::getCategoryId, categoryId) .eq(Dish::getStatus, 1) .orderByDesc(Dish::getSales); dishMapper.selectPage(pageInfo, wrapper); PageResult<Dish> result = new PageResult<>(pageInfo.getRecords(), pageInfo.getTotal()); redisTemplate.opsForValue().set(key, result, 10, TimeUnit.MINUTES); return result; } }5.3 提交订单
用户提交订单时,后端需要校验菜品库存和价格,创建订单主表和明细表,并调用微信支付统一下单接口。
@Transactional public OrderVO createOrder(OrderDTO dto, Long userId) { // 1. 计算订单总金额 BigDecimal total = BigDecimal.ZERO; List<OrderItem> items = new ArrayList<>(); for (OrderItemDTO item : dto.getItems()) { Dish dish = dishMapper.selectById(item.getDishId()); if (dish == null || dish.getStatus() != 1) { throw new BusinessException("菜品不存在或已下架"); } total = total.add(dish.getPrice().multiply(BigDecimal.valueOf(item.getQuantity()))); OrderItem orderItem = new OrderItem(); orderItem.setDishId(dish.getId()); orderItem.setDishName(dish.getName()); orderItem.setPrice(dish.getPrice()); orderItem.setQuantity(item.getQuantity()); items.add(orderItem); } // 2. 创建订单主表 Orders order = new Orders(); order.setOrderNo(generateOrderNo()); order.setUserId(userId); order.setTotalAmount(total); order.setStatus(0); order.setRemark(dto.getRemark()); orderMapper.insert(order); // 3. 创建订单明细 for (OrderItem item : items) { item.setOrderId(order.getId()); orderItemMapper.insert(item); } // 4. 调用微信支付统一下单 String prepayId = wxPayService.unifiedOrder(order.getOrderNo(), total); return new OrderVO(order, prepayId); }5.4 小程序端购物车页面
购物车使用本地缓存wx.setStorageSync存储,减少与服务端交互,提升响应速度。
Page({ data: { cartList: [], totalPrice: 0, totalCount: 0 }, onShow() { this.loadCart(); }, loadCart() { const cart = wx.getStorageSync('cart') || []; let totalPrice = 0; let totalCount = 0; cart.forEach(item => { totalPrice += item.price * item.quantity; totalCount += item.quantity; }); this.setData({ cartList: cart, totalPrice: totalPrice.toFixed(2), totalCount: totalCount }); }, changeQuantity(e) { const index = e.currentTarget.dataset.index; const type = e.currentTarget.dataset.type; const cart = this.data.cartList; if (type === 'add') { cart[index].quantity++; } else { cart[index].quantity--; if (cart[index].quantity <= 0) { cart.splice(index, 1); } } wx.setStorageSync('cart', cart); this.loadCart(); }, submitOrder() { const cart = this.data.cartList; if (cart.length === 0) { wx.showToast({ title: '购物车为空', icon: 'none' }); return; } // 跳转到确认订单页面 wx.navigateTo({ url: '/pages/order/confirm' }); } });6. 系统测试与总结
6.1 功能测试
系统核心功能测试覆盖用户登录、菜品浏览、购物车管理、订单提交和支付回调等场景。测试结果表明,各模块功能正常,接口响应时间平均在 200 毫秒以内,满足设计预期。
6.2 总结与展望
本文设计并实现了一个基于微信小程序的烧烤店订餐系统,采用 Spring Boot 与微信小程序原生框架的前后端分离架构,实现了用户登录、菜品管理、购物车、订单支付等核心功能。系统有效提升了烧烤店的点餐效率和用户体验。
后续可从以下方向继续优化:
- 引入消息队列(如 RabbitMQ)处理高并发订单,提升系统吞吐量。
- 增加会员积分和优惠券体系,提升用户粘性。
- 接入配送服务,实现外卖配送全流程跟踪。
- 基于用户消费数据构建推荐系统,实现个性化菜品推荐。