1. 项目概述SpringBoot餐厅点餐微信小程序去年接手过一个连锁餐饮集团的数字化改造项目当时用SpringBoot微信小程序重构了他们的点餐系统。这个技术栈的选择绝非偶然——SpringBoot的快速开发特性完美匹配餐饮行业频繁的需求变更而微信小程序则解决了传统餐饮App获客成本高的痛点。实测上线后客户门店的翻台率提升了23%服务员人力成本降低了15%。整套系统采用经典的三层架构前端微信小程序WXMLWXSS后端SpringBoot 2.7 MyBatis Plus数据库MySQL 8.0读写分离配置2. 核心功能模块拆解2.1 微信小程序端功能实现在微信开发者工具中创建项目时建议勾选不使用云开发选项小程序目录结构会因此不同。核心页面包括// 典型页面结构 pages/ ├── index/ // 首页 ├── menu/ // 菜单页 ├── cart/ // 购物车 ├── order/ // 订单页 └── user/ // 个人中心特别注意这几个微信API的使用技巧wx.login()获取code后需要立即调用后端接口code有效期仅5分钟购物车数据建议同时存到wx.setStorageSync()和全局变量中防止页面切换时数据丢失支付环节必须处理wx.requestPayment的fail回调实测约有3%的用户会支付失败2.2 SpringBoot后端关键设计用IDEA创建项目时推荐选择这些依赖Spring WebMyBatis FrameworkMySQL DriverLombok减少样板代码数据库表设计有个容易踩的坑菜品表需要设计current_price和original_price双字段而不是只存折扣率。因为餐饮行业经常有第二份半价这类复杂促销单纯用折扣率字段会导致计算逻辑复杂化。// 典型Controller示例 RestController RequestMapping(/api/order) public class OrderController { Autowired private OrderService orderService; PostMapping(/create) public Result createOrder(RequestBody OrderDTO orderDTO) { // 参数校验应放在DTO的Valid注解中 return orderService.createOrder(orderDTO); } }3. 开发过程中的典型问题解决方案3.1 微信用户体系对接很多开发者会直接使用微信的openid作为用户主键这是非常危险的做法。正确姿势应该是小程序端调用wx.login()获取code将code传到后端后端用codeappidsecret换取session_key和openid生成自定义token返回给小程序// 用户登录服务层代码片段 public String wxLogin(String code) { // 1. 构造请求URL String url https://api.weixin.qq.com/sns/jscode2session? appid appId secret appSecret js_code code grant_typeauthorization_code; // 2. 发送HTTP请求 String response restTemplate.getForObject(url, String.class); JSONObject json JSON.parseObject(response); // 3. 处理响应 String openid json.getString(openid); if(StringUtils.isEmpty(openid)) { throw new BusinessException(微信登录失败); } // 4. 创建/更新用户记录 User user userMapper.selectByOpenid(openid); if(user null) { user new User(); user.setOpenid(openid); userMapper.insert(user); } // 5. 生成JWT token return JwtUtil.generateToken(user.getId()); }3.2 高并发下单处理餐饮高峰期经常出现多人同时抢购特价菜的情况。我们通过以下方案解决使用Redis分布式锁控制库存扣减订单表做水平分表按月份拆分引入消息队列削峰填谷// 基于Redisson的分布式锁实现 public boolean reduceStock(Long dishId, Integer quantity) { String lockKey dish_stock_lock: dishId; RLock lock redissonClient.getLock(lockKey); try { // 尝试加锁最多等待100ms锁持有时间30s if(lock.tryLock(100, 30000, TimeUnit.MILLISECONDS)) { Dish dish dishMapper.selectById(dishId); if(dish.getStock() quantity) { dish.setStock(dish.getStock() - quantity); dishMapper.updateById(dish); return true; } return false; } } catch (InterruptedException e) { Thread.currentThread().interrupt(); } finally { if(lock.isHeldByCurrentThread()) { lock.unlock(); } } return false; }4. 部署与性能优化实战4.1 微信小程序审核要点提交审核时最容易被打回的三个问题未处理用户拒绝授权的情况必须在fail回调中给出替代方案表单缺少必填项校验特别是收货地址相关字段支付流程未提供测试环境白名单必须在代码中区分开发/生产环境4.2 SpringBoot生产环境配置推荐使用这种多环境配置方式# application-dev.yml server: port: 8080 spring: datasource: url: jdbc:mysql://localhost:3306/restaurant_dev username: devuser password: dev123 # application-prod.yml server: port: 80 spring: datasource: url: jdbc:mysql://prod-db:3306/restaurant_prod?useSSLtrue username: produser password: ${DB_PASSWORD} # 从环境变量读取启动时通过--spring.profiles.activeprod指定环境。关键优化参数server.tomcat.max-threads200默认只有50spring.servlet.multipart.max-file-size10MB微信小程序图片上传限制mybatis-plus.configuration.cache-enabledtrue4.3 监控与日志处理我们使用ELK栈收集日志时发现微信小程序特有的问题需要特别关注网络切换时的请求重发会导致重复下单iOS/android平台差异特别是日期格式化低端机型的性能问题配置Logback时建议这样区分日志级别logger namecom.wechat levelDEBUG/ logger nameorg.springframework.web levelWARN/ logger nameorg.mybatis levelINFO/5. 源码解析与二次开发建议项目源码中最值得研究的几个核心类WeChatPayService.java- 处理微信支付的所有回调逻辑CartServiceImpl.java- 使用Redis本地缓存双写策略ScheduledTasks.java- 定时处理超时未支付订单二次开发时推荐先修改这些配置# 小程序配置 wx.app-id你的appid wx.app-secret你的secret # 支付配置 wx.pay.mch-id商户号 wx.pay.key-pathclasspath:/cert/apiclient_key.pem # 短信配置用于订单通知 sms.access-key阿里云accessKey对于想要添加新功能的开发者建议从这几个低风险模块入手菜品评价系统新建rating表会员积分体系在用户表添加points字段桌台管理系统适合有实体门店的场景