这是一个基于 Spring Boot + Vue 3 的前后端分离餐厅点餐系统,覆盖顾客扫码点餐、服务员桌台管理、后厨制作看板、菜品库存管理、订单结算、评价统计和运营报表等流程。
项目适合作为数据库课程设计、Java Web 课程设计或前后端分离综合实践项目。
restaurant
├─ restaurant-backend Spring Boot 后端服务
├─ restaurant-admin 管理端:管理员、服务员、厨师使用
├─ restaurant-customer 顾客端 Web 版:扫码点餐、查看订单、支付评价
├─ restaurant-miniprogram 顾客端微信小程序版
├─ docs 专项说明文档
│ ├─ DOCKER_TROUBLESHOOTING.md Docker 部署与登录问题排查
│ ├─ WECHAT_MINIPROGRAM.md 微信小程序联调说明
│ ├─ REDIS.md Redis 可选增强说明
│ └─ CHANGELOG.md 近期变更记录
├─ ROADMAP.md 后续完善路线
└─ 项目问题总结与知识点.md
后端:
- Spring Boot 3
- Spring MVC
- Spring Security
- JWT
- MyBatis
- MySQL
- Maven
前端:
- Vue 3
- Vite
- Vue Router
- Axios
- 原生 CSS
小程序:
- 微信原生小程序
- WXML / WXSS / JavaScript
wx.request- 本地缓存
wx.setStorageSync
- Web 版支持通过 URL 参数带入桌号,例如
/menu?table=3。 - 小程序版支持通过桌台二维码进入点餐页,例如
pages/table/table?tableId=1。 - 小程序版支持
scene参数,适配微信小程序码扫码进入桌台。 - 支持浏览菜单、分类筛选、搜索菜品。
- 支持菜品图片展示,未上传图片时显示缺省占位。
- 点菜页底部购物车可展开查看未下单菜品。
- 小程序点菜页支持菜品步进器,支持
+/-和键盘输入份数。 - 新菜品点击“下单”后直接生成订单。
- 已下单且没有新增菜品时显示“去支付”。
- 订单页展示已点菜品、订单金额、厨房制作状态。
- 支持顾客催单,催单信息会同步到厨房看板。
- 支持呼叫服务员,管理端首页显示待处理服务呼叫。
- 支付页展示已点菜品详情,模拟支付成功后释放桌台。
- 支持提交评价。
- JWT 登录和角色权限控制。
- 用户管理:新增、修改、重置密码、禁用/启用账号、修改角色。
- 分类管理:新增、修改、删除菜品分类。
- 菜品管理:新增、编辑、删除、批量上架/下架、库存预警、上传菜品图片。
- 桌台管理:开台、点菜、加菜、退菜、关台、结账。
- 支持换桌、并桌和合并订单。
- 今日订单支持搜索、金额区间、日期、时段和状态筛选。
- 首页展示今日订单、已收金额、未收金额、空闲桌位、低库存菜品。
- 首页展示待处理服务呼叫,可标记已处理。
- 桌台卡片可生成扫码点单二维码,支持下载打印。
- 报表支持热销菜品、低库存菜品、评价筛选、退菜原因统计。
- 按菜品制作状态展示厨房队列。
- 支持状态流转:待制作、制作中、待上菜、已上菜。
- 支持按等待时间高亮提醒。
- 顾客催单后,厨房看板显示催单次数和最近催单时间。
- 已支付且所有菜品已上菜后,订单可自动完成。
- 一桌一单:同一桌未结账时,加菜会追加到当前订单。
- 小程序扫码进入桌台时,会按桌台找回当前
PENDING或PAID订单。 - 同一道菜重复加菜时,合并数量,不重复插入明细。
- 下单扣减库存,并写入
stock_change_log的ORDER_CREATE/OUT流水。 - 取消订单和退菜回库会恢复库存,并写入
ORDER_CANCEL/IN或REFUND_RETURN/IN流水;退菜同时同步订单金额。 - 管理端手动调整菜品库存时,会按差值写入
MANUAL_ADJUST/IN|OUT流水。 - 支付成功后释放桌台。
- 管理端结账后订单完成并释放桌台。
请先启动 MySQL,并创建数据库:
CREATE DATABASE restaurant_db DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
USE restaurant_db;然后按顺序执行:
source restaurant-backend/src/main/resources/sql/schema.sql;
source restaurant-backend/src/main/resources/sql/data.sql;如果你是在旧数据库上升级,需要再根据实际情况执行迁移脚本:
source restaurant-backend/src/main/resources/sql/migration-add-order-detail-remark.sql;
source restaurant-backend/src/main/resources/sql/migration-add-detail-status.sql;
source restaurant-backend/src/main/resources/sql/migration-add-order-reminder.sql;
source restaurant-backend/src/main/resources/sql/migration-current-db-fixes.sql;
source restaurant-backend/src/main/resources/sql/migration-add-waiter-call.sql;
source restaurant-backend/src/main/resources/sql/migration-add-user-wx-openid.sql;migration-current-db-fixes.sql 目前同时负责旧库补齐 order_detail.status、订单催单字段、最新版 v_kitchen_queue 视图,以及 stock_change_log 库存变动流水表。旧版 migration-add-detail-status.sql 不再重复创建 v_kitchen_queue。
当前默认数据库配置在:
restaurant-backend/src/main/resources/application.yml
默认连接信息:
spring:
datasource:
url: ${SPRING_DATASOURCE_URL:jdbc:mysql://localhost:3306/restaurant_db}
username: ${SPRING_DATASOURCE_USERNAME:root}
password: ${SPRING_DATASOURCE_PASSWORD}数据库密码不再写入 application.yml,必须通过环境变量或根目录 .env 提供:
SPRING_DATASOURCE_PASSWORD=你的数据库密码JWT 密钥也必须通过环境变量提供,长度至少 32 字节,且不能继续使用旧的 change-me 默认值:
JWT_SECRET=至少32位的随机字符串本地开发可复制 .env.example 为 .env 后修改其中的占位值;.env 已加入忽略列表,不应提交到仓库。
| 角色 | 手机号 | 密码 | 说明 |
|---|---|---|---|
| 管理员 | 13800000000 | 123456 | 拥有全部管理权限 |
| 服务员 | 13800000001 | 123456 | 开台、点菜、退菜、结账 |
| 厨师 | 13800000002 | 123456 | 菜品管理、分类管理、厨房看板 |
| 顾客 | 13800000003 | 123456 | 顾客端点餐、支付、评价 |
项目已提供 Docker 配置,可一次启动 MySQL、Redis、后端、管理端和顾客端 Web。
MyBatis 是后端内部 ORM 框架,随 restaurant-backend 容器一起运行,不需要单独容器。
首次启动前,先准备环境变量文件:
copy .env.example .env然后编辑 .env,至少设置:
MYSQL_ROOT_PASSWORD
SPRING_DATASOURCE_PASSWORD
JWT_SECRET
在项目根目录运行:
docker compose up -d --build启动后访问:
管理端:http://localhost:5173
顾客端:http://localhost:5174
后端:http://localhost:8080
查看容器状态:
docker compose ps查看日志:
docker compose logs -f backend
docker compose logs -f admin
docker compose logs -f mysql
docker compose logs -f redis停止容器:
docker compose down当前 Docker 配置中,MySQL 和 Redis 只在 Docker 内部网络暴露。后端通过 mysql:3306 访问数据库,通过 redis:6379 访问 Redis;宿主机不映射 MySQL / Redis 端口,避免和本机服务或 Windows 保留端口冲突。
如果需要完全重建数据库:
docker compose down -v
docker compose up -d --build注意:down -v 会删除数据库卷,现有数据会丢失。
Docker 部署和登录排障记录见:docs/DOCKER_TROUBLESHOOTING.md
在后端项目目录运行,也就是包含 pom.xml 的目录:
cd restaurant-backend
mvn spring-boot:run后端默认地址:
http://localhost:8080
直接运行后端前,需要先设置:
set SPRING_DATASOURCE_PASSWORD=你的数据库密码
set JWT_SECRET=至少32位的随机字符串PowerShell 可使用:
$env:SPRING_DATASOURCE_PASSWORD="你的数据库密码"
$env:JWT_SECRET="至少32位的随机字符串"在管理端项目目录运行,也就是包含 package.json 的目录:
cd restaurant-admin
npm install
npm run dev管理端默认地址:
http://localhost:5173
在顾客端项目目录运行,也就是包含 package.json 的目录:
cd restaurant-customer
npm install
npm run dev顾客端默认地址:
http://localhost:5174
示例扫码点餐地址:
http://localhost:5174/menu?table=1
在微信开发者工具中打开目录:
restaurant-miniprogram
开发阶段后端地址在:
restaurant-miniprogram/miniprogram/config/index.js
默认是:
var API_BASE_URL = 'http://localhost:8080'微信一键登录需要后端配置微信小程序信息:
set WECHAT_APP_ID=你的微信小程序AppID
set WECHAT_APP_SECRET=你的微信小程序AppSecret或在 WSL/Linux 中:
export WECHAT_APP_ID=你的微信小程序AppID
export WECHAT_APP_SECRET=你的微信小程序AppSecret然后重启后端。
如果未配置,手机号密码登录仍可使用,微信登录会提示后端未配置微信小程序信息。
在微信开发者工具中模拟扫码:
- 点击“普通编译”旁边的下拉菜单。
- 选择“添加编译模式”。
- 启动页面填写:
pages/table/table。 - 启动参数填写:
tableId=1或tableNumber=A02。
更多小程序联调说明见:docs/WECHAT_MINIPROGRAM.md
后端编译:
cd restaurant-backend
mvn -q -DskipTests package后端接口文档:
http://localhost:8080/swagger-ui/index.html
OpenAPI JSON:
http://localhost:8080/v3/api-docs
管理端打包:
cd restaurant-admin
npm install
npm run build顾客端打包:
cd restaurant-customer
npm run build菜品管理中上传的图片会保存到后端运行目录下:
restaurant-backend/uploads/dishes/
数据库中保存的图片路径类似:
/uploads/dishes/xxxxxxxx.jpg
后端通过 /uploads/** 对外提供静态资源访问。管理端和顾客端的 vite.config.js 已配置 /uploads 代理到后端,所以开发环境下上传后可以直接在页面看到图片。
后端安全配置已放行:
/uploads/**
如果图片上传成功但页面不显示,请检查:
- 后端是否已启动。
- 管理端或顾客端是否已重启。
- 图片路径是否以
/uploads/dishes/开头。 - 浏览器开发者工具 Network 中图片请求是否为 403 或 404。
- 如果是 403,请确认后端已重启,使
/uploads/**放行配置生效。
小程序真机调试时,localhost 指向手机自身,不是开发电脑。真机应使用电脑局域网 IP 或 HTTPS 域名:
var API_BASE_URL = 'http://192.168.0.101:8080'局域网 IP 调试需要同时满足:
- 手机和电脑处于同一个可互访网络。
- 手机浏览器可以打开
http://电脑IP:8080/api/tables。 - Windows 防火墙已放行
8080入站。 - 如果后端运行在 WSL 中,Windows 已配置
portproxy将电脑IP:8080转发到 WSL 后端。 - 微信开发者工具本地设置中已勾选“不校验合法域名、web-view、TLS 版本以及 HTTPS 证书”。
如果接口能访问但小程序图片不显示,请用手机浏览器打开图片地址确认:
http://电脑IP:8080/uploads/dishes/图片名.png
浏览器能打开但小程序仍不显示时,优先考虑切换到 HTTPS 合法域名;正式上线必须使用 HTTPS 域名,并在微信公众平台配置 request、uploadFile、downloadFile 合法域名。
| 角色 | 可访问模块 | 主要限制 |
|---|---|---|
| 管理员 | 全部页面 | 无 |
| 服务员 | 首页、桌台订单、菜品统计 | 不能进入用户管理等管理员专属页面 |
| 厨师 | 首页、菜品管理、分类管理、厨房看板、报表 | 首页只读桌台订单,不能开台、点菜、退菜、结账 |
| 顾客 | 顾客端页面 | 不能访问管理端接口 |
权限控制分两层:
- 前端:通过路由
meta.roles和导航过滤控制页面入口。 - 后端:通过
@PreAuthorize控制接口权限。
前端权限只是为了改善体验,真正的安全控制以后端权限为准。
Redis 是一个可选的增强组件。Docker Compose 部署时默认启用 Redis;本机 Windows 开发时默认不启用,仍然可以开箱即用。
- Windows 本机开发环境:
APP_REDIS_ENABLED=false,使用内存级 JWT 黑名单和缓存。 - Docker Compose 环境:
APP_REDIS_ENABLED=true,使用restaurant-redis容器提供 Redis 黑名单和 Redis CacheManager。
Docker Compose 已内置 Redis 服务。手动运行后端时,也可以通过环境变量启用 Redis,以获得持久化的 JWT 黑名单和分布式缓存能力。
Docker Compose 中确认 Redis:
docker compose ps redis
docker compose logs -f redis手动开发时启用 Redis:
export APP_REDIS_ENABLED=true
export SPRING_DATA_REDIS_HOST=localhost
export SPRING_DATA_REDIS_PORT=6379详细步骤见:docs/REDIS.md
- JWT 登出接口
POST /api/auth/logout:登录用户调用后 token 立即失效 - Redis 缓存:可用
@Cacheable缓存菜品、分类等查询
Docker 部署后如果遇到端口绑定失败、登录后又回到登录页、首页接口 401/403/500 等问题,先看:
docs/DOCKER_TROUBLESHOOTING.md
重点排查:
docker compose ps中容器是否都为Up。docker compose logs -f backend是否有后端异常。- 浏览器 Network 中
/api/auth/login和首页初始化接口的状态码。 - 登录后
localStorage是否保存了 token。 - 请求头是否带有
Authorization: Bearer xxx。 - 数据库中的角色名是否为正常中文,例如
管理员,而不是乱码。
请检查:
- MySQL 是否启动。
- 是否已经创建
restaurant_db。 application.yml中的用户名和密码是否正确。
请确认:
- 后端是否运行在
8080端口。 - 前端是否运行在正确目录。
- 浏览器控制台是否有 401、403、404、500 错误。
- 登录是否过期,必要时重新登录。
如果接口返回 500,前端只会显示统一提示:
系统繁忙,请稍后再试
真实异常不会再暴露给前端,需要到后端日志中查看。常用入口:
- 本地直接运行后端:查看 IDE 控制台或
mvn spring-boot:run所在终端。 - 当前项目根目录日志:查看
backend_output.log。 - Docker 部署:执行
docker compose logs -f backend。
日志中搜索 Unhandled exception,后面会跟完整异常堆栈,通常可以看到 SQL、业务代码或依赖调用的真实错误。
说明旧数据库缺少催单字段。请执行:
source restaurant-backend/src/main/resources/sql/migration-add-order-reminder.sql;
source restaurant-backend/src/main/resources/sql/migration-current-db-fixes.sql;执行后重启后端。
请检查:
- 订单是否已经成功下单。
order_detail.status字段是否存在。v_kitchen_queue视图是否已由schema.sql或migration-current-db-fixes.sql创建为最新版。- 旧数据库是否执行过迁移脚本。
请确认前端已重启,因为 /uploads 代理配置在 vite.config.js 中,修改后需要重启 Vite 开发服务器。
如果小程序中菜品图片不显示,请确认:
- 后端已重启。
restaurant-miniprogram/miniprogram/config/index.js中的API_BASE_URL能访问后端。- 开发者工具已关闭合法域名校验,或正式环境已配置 HTTPS 合法域名。
- 图片请求不是 403;如果是 403,说明后端静态资源放行配置未生效。
后续计划记录在:
ROADMAP.md
近期变更记录在:
docs/CHANGELOG.md
Docker 部署和排障记录在:
docs/DOCKER_TROUBLESHOOTING.md
已完成前四阶段:稳定性与文档统一、订单业务闭环、顾客端体验增强、管理端运营能力。
后续可以继续完善:
- 接口测试清单。
- 更细粒度的角色权限说明。