Skip to content

Repository files navigation

餐厅点餐系统

这是一个基于 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

三、核心功能

1. 顾客端

  • Web 版支持通过 URL 参数带入桌号,例如 /menu?table=3
  • 小程序版支持通过桌台二维码进入点餐页,例如 pages/table/table?tableId=1
  • 小程序版支持 scene 参数,适配微信小程序码扫码进入桌台。
  • 支持浏览菜单、分类筛选、搜索菜品。
  • 支持菜品图片展示,未上传图片时显示缺省占位。
  • 点菜页底部购物车可展开查看未下单菜品。
  • 小程序点菜页支持菜品步进器,支持 +/- 和键盘输入份数。
  • 新菜品点击“下单”后直接生成订单。
  • 已下单且没有新增菜品时显示“去支付”。
  • 订单页展示已点菜品、订单金额、厨房制作状态。
  • 支持顾客催单,催单信息会同步到厨房看板。
  • 支持呼叫服务员,管理端首页显示待处理服务呼叫。
  • 支付页展示已点菜品详情,模拟支付成功后释放桌台。
  • 支持提交评价。

2. 管理端

  • JWT 登录和角色权限控制。
  • 用户管理:新增、修改、重置密码、禁用/启用账号、修改角色。
  • 分类管理:新增、修改、删除菜品分类。
  • 菜品管理:新增、编辑、删除、批量上架/下架、库存预警、上传菜品图片。
  • 桌台管理:开台、点菜、加菜、退菜、关台、结账。
  • 支持换桌、并桌和合并订单。
  • 今日订单支持搜索、金额区间、日期、时段和状态筛选。
  • 首页展示今日订单、已收金额、未收金额、空闲桌位、低库存菜品。
  • 首页展示待处理服务呼叫,可标记已处理。
  • 桌台卡片可生成扫码点单二维码,支持下载打印。
  • 报表支持热销菜品、低库存菜品、评价筛选、退菜原因统计。

3. 后厨看板

  • 按菜品制作状态展示厨房队列。
  • 支持状态流转:待制作、制作中、待上菜、已上菜。
  • 支持按等待时间高亮提醒。
  • 顾客催单后,厨房看板显示催单次数和最近催单时间。
  • 已支付且所有菜品已上菜后,订单可自动完成。

4. 订单与库存

  • 一桌一单:同一桌未结账时,加菜会追加到当前订单。
  • 小程序扫码进入桌台时,会按桌台找回当前 PENDINGPAID 订单。
  • 同一道菜重复加菜时,合并数量,不重复插入明细。
  • 下单扣减库存,并写入 stock_change_logORDER_CREATE/OUT 流水。
  • 取消订单和退菜回库会恢复库存,并写入 ORDER_CANCEL/INREFUND_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 顾客端点餐、支付、评价

六、启动项目

0. Docker Compose 一键启动(推荐)

项目已提供 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

1. 启动后端

在后端项目目录运行,也就是包含 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位的随机字符串"

2. 启动管理端

在管理端项目目录运行,也就是包含 package.json 的目录:

cd restaurant-admin
npm install
npm run dev

管理端默认地址:

http://localhost:5173

3. 启动顾客端

在顾客端项目目录运行,也就是包含 package.json 的目录:

cd restaurant-customer
npm install
npm run dev

顾客端默认地址:

http://localhost:5174

示例扫码点餐地址:

http://localhost:5174/menu?table=1

4. 打开微信小程序顾客端

在微信开发者工具中打开目录:

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

然后重启后端。

如果未配置,手机号密码登录仍可使用,微信登录会提示后端未配置微信小程序信息。

在微信开发者工具中模拟扫码:

  1. 点击“普通编译”旁边的下拉菜单。
  2. 选择“添加编译模式”。
  3. 启动页面填写:pages/table/table
  4. 启动参数填写:tableId=1tableNumber=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(可选)

Redis 是一个可选的增强组件。Docker Compose 部署时默认启用 Redis;本机 Windows 开发时默认不启用,仍然可以开箱即用。

默认行为

  • Windows 本机开发环境:APP_REDIS_ENABLED=false,使用内存级 JWT 黑名单和缓存。
  • Docker Compose 环境:APP_REDIS_ENABLED=true,使用 restaurant-redis 容器提供 Redis 黑名单和 Redis CacheManager。

启用 Redis(Docker / WSL / Linux)

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 缓存菜品、分类等查询

十二、常见问题

0. Docker 启动或登录异常

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
  • 数据库中的角色名是否为正常中文,例如 管理员,而不是乱码。

1. 后端启动失败,提示数据库连接失败

请检查:

  • MySQL 是否启动。
  • 是否已经创建 restaurant_db
  • application.yml 中的用户名和密码是否正确。

2. 页面请求接口失败

请确认:

  • 后端是否运行在 8080 端口。
  • 前端是否运行在正确目录。
  • 浏览器控制台是否有 401、403、404、500 错误。
  • 登录是否过期,必要时重新登录。

如果接口返回 500,前端只会显示统一提示:

系统繁忙,请稍后再试

真实异常不会再暴露给前端,需要到后端日志中查看。常用入口:

  • 本地直接运行后端:查看 IDE 控制台或 mvn spring-boot:run 所在终端。
  • 当前项目根目录日志:查看 backend_output.log
  • Docker 部署:执行 docker compose logs -f backend

日志中搜索 Unhandled exception,后面会跟完整异常堆栈,通常可以看到 SQL、业务代码或依赖调用的真实错误。

3. 催单时报 Unknown column 'reminder_count'

说明旧数据库缺少催单字段。请执行:

source restaurant-backend/src/main/resources/sql/migration-add-order-reminder.sql;
source restaurant-backend/src/main/resources/sql/migration-current-db-fixes.sql;

执行后重启后端。

4. 厨房看板没有显示新订单

请检查:

  • 订单是否已经成功下单。
  • order_detail.status 字段是否存在。
  • v_kitchen_queue 视图是否已由 schema.sqlmigration-current-db-fixes.sql 创建为最新版。
  • 旧数据库是否执行过迁移脚本。

5. 顾客端图片不显示

请确认前端已重启,因为 /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

已完成前四阶段:稳定性与文档统一、订单业务闭环、顾客端体验增强、管理端运营能力。

后续可以继续完善:

  • 接口测试清单。
  • 更细粒度的角色权限说明。

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages