# 小餐馆点餐系统 **Repository Path**: dnboy/EatEasy ## Basic Information - **Project Name**: 小餐馆点餐系统 - **Description**: EatEasy 是一款面向小型餐馆的全功能点餐收银系统,覆盖堂食、早餐、外卖三大场景。顾客可扫码自助点餐或由服务员/管理员代客点餐;支持会员储值、充值赠送、积分、优惠券、多支付方式、订单小票/发票打印、叫号取餐、菜品取消、退款(部分/整单)、外卖平台对接(美团/淘宝闪购/京东外卖)以及丰富的销售报表统计。 目标用户:中小型餐馆(10-50 桌),顾客、服务员、后厨、收银/管理员 - **Primary Language**: Unknown - **License**: MulanPSL-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2026-07-11 - **Last Updated**: 2026-07-14 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # EatEasy 小餐馆点餐收银系统 一款面向小型餐馆的全功能点餐收银系统,覆盖堂食、早餐、外卖三大场景。 ## 系统界面 ### 管理端 | 今日概览 | 订单管理 | |:---:|:---:| | ![今日概览](docs/screenshots/admin-dashboard.png) | ![订单管理](docs/screenshots/admin-orders.png) | | 菜单管理 | 餐桌管理 | |:---:|:---:| | ![菜单管理](docs/screenshots/admin-menu.png) | ![餐桌管理](docs/screenshots/admin-tables.png) | | 预定管理 | 收银台 | |:---:|:---:| | ![预定管理](docs/screenshots/admin-reservations.png) | ![收银台](docs/screenshots/admin-cashier.png) | | 销售报表 | 会员管理 | |:---:|:---:| | ![销售报表](docs/screenshots/admin-reports.png) | ![会员管理](docs/screenshots/admin-members.png) | | 发票管理 | 退款管理 | |:---:|:---:| | ![发票管理](docs/screenshots/admin-invoices.png) | ![退款管理](docs/screenshots/admin-refunds.png) | | 系统设置 | 员工管理 | |:---:|:---:| | ![系统设置](docs/screenshots/admin-settings.png) | ![员工管理](docs/screenshots/admin-staff.png) | | 代客点餐(时段选择) | |:---:| | ![代客点餐](docs/screenshots/admin-new-order-timeslot.png) | ### 顾客端 | 扫码点餐 | 扫码关联餐桌 | |:---:|:---:| | ![扫码点餐](docs/screenshots/customer-menu.png) | ![扫码关联餐桌](docs/screenshots/customer-menu-table.png) | | 购物车 | 订单追踪 | |:---:|:---:| | ![购物车](docs/screenshots/customer-cart.png) | ![订单追踪](docs/screenshots/customer-order.png) | | 会员中心 | |:---:| | ![会员中心](docs/screenshots/customer-member.png) | ## 功能概览 ### 顾客端 - **扫码点餐**:扫码自动关联餐桌号,根据餐桌状态智能处理 - 空闲餐桌:直接点餐下单 - 公共餐桌(public)占用中:可选择「加菜到当前订单」或「新建订单」 - 大堂餐桌(lobby)占用中:仅允许「加菜到当前订单」 - 包间占用中:自动合并到当前订单 - **菜品浏览**:分类浏览、搜索、规格选择(大小份/加料/口味) - **购物车管理**:单品备注、整单备注、数量调整 - **支付方式**:仅支持线上支付(微信/支付宝),顾客端不允许现金支付 - **优惠券**:优惠券选择、会员折扣 - **订单追踪**:订单状态实时追踪、取餐号查询 - **加菜/取消**:可加菜到已有订单,可取消未制作菜品 - **会员中心**:注册/登录、余额查询、充值赠送、积分、消费记录 - **排队取号**:在线取号、查看排队进度 - **预定点餐**:支持选择餐桌、查看预定状态 ### 管理端 - **今日概览**:订单数、营业额、堂食/带走/早餐/午餐/晚餐/外卖平台等多维度数据 - **订单管理**:全部订单、状态筛选、代客点餐、菜品取消、退款、打印 - **菜单管理**:菜品 CRUD、上下架、规格/加料、套餐、库存、时段价(早餐/午餐/晚餐差异化定价) - **代客点餐**:支持时段选择(早餐/午餐/晚餐),加载对应时段菜品和价格 - **餐桌管理**:状态管理、二维码生成、智能预定状态判断 - 公共餐桌(public):虚拟餐桌,允许多订单同时存在 - 大堂餐桌(lobby):普通餐桌,占用时拒绝新订单 - 包间(private_room):独占使用,占用时拒绝新订单 - **预定管理**:多桌预定、定金支付(支持定金比例设置)、预定菜品管理、取消退定金 - **会员管理**:会员列表、充值、充值规则、积分规则、等级 - 会员充值:线上支付需配置支付网关,沙箱测试网关仅限测试模式 - 现金充值:仅限后台操作,顾客端不可自行现金充值 - **收银台**:多支付方式(微信/支付宝/现金/会员余额/组合支付)、找零 - **退款管理**:部分退款、整单退款、原路/现金/会员余额退回、操作人记录、订单号追踪 - **外卖对接**:美团/淘宝闪购/京东外卖、菜单映射、自动接单 - **销售报表**:营业额趋势(近7/30/90天/1年/今年/去年)、时段分析、菜品排行、支付占比、会员分析、多维度统计 - **活动营销**:优惠券(满减/折扣/赠菜券含有效期)、充值赠送活动 - **排队管理**:取号、叫号、入座 - **交班管理**:交接班、交班报表、现金盘点 - **员工管理**:账号管理、5种角色权限(管理员/店长/收银员/服务员/后厨) - **发票管理**:抬头管理、开票、打印、换开功能、额度管理 - **系统设置**:店铺信息、支付模式、营业时间、发票额度、预定定金比例、测试模式开关 - **虚拟公共餐桌**:始终可用,不受就餐状态影响,允许多订单并存 ## 核心业务流程 ### 订单全生命周期 ``` 创建订单 → 确认订单 → 制作中 → 出餐完成 → 取餐 → 结账 → 释放餐桌 ↓ ↓ ↓ 取消订单 加菜/减菜 取消未制作菜品 ``` ### 结账条件校验 结账需同时满足以下条件: 1. 所有非取消菜品已出餐(状态为 `ready`) 2. 订单已全额支付(`paidAmount >= payPrice`) 3. 结账后自动释放餐桌(若无其他活跃订单) ### 支付安全机制 | 场景 | 规则 | |------|------| | 顾客端支付 | 仅允许线上支付(微信/支付宝),禁止现金支付 | | 管理端支付 | 支持所有支付方式(含现金) | | 沙箱支付网关 | 仅在测试模式下可用,生产环境自动拒绝 | | 支付验证 | 所有在线支付需校验支付结果,避免虚假支付 | | 部分支付 | 支持,通过 `paidAmount` 跟踪累计支付金额 | | 加菜补差价 | 加菜后 `payPrice` 增加,`paidAmount` 不变,需补差价 | | 支付幂等性(v3.1) | 支持 `idempotencyKey`,相同 key 的重复请求返回缓存结果,避免重复扣款 | | 退款流水记录(v3.1) | 每笔退款创建 `RefundRecord`,记录渠道流水号、回调状态、对账状态 | | 会员乐观锁(v3.1) | 会员余额变更时 `version` 字段递增 + DB 级原子 `WHERE version = ?` 校验,并发冲突返回 409;本金优先扣减、按比例退回 | | 积分流水审计(v3.1) | 所有积分变动产生 `PointTransaction` 记录,含来源、余额快照、过期时间 | | 现金流水(v3.1) | 现金收支记录到 `CashTransaction`,支持交班关联查询 | | 积分过期清理(v3.1) | 定时扫描过期积分(24h 间隔),自动扣减并记录流水 | ### 餐桌状态管理 | 餐桌类型 | 占用中行为 | 结账后行为 | |----------|-----------|-----------| | 公共餐桌(public) | 允许新建多个订单 | 检查是否还有其他活跃订单 | | 大堂餐桌(lobby) | 拒绝新建订单 | 释放餐桌 | | 包间(private_room) | 拒绝新建订单(独占) | 释放餐桌 | | 已预定(reserved) | 拒绝新建订单 | 保持预定状态 | ## 测试覆盖 本项目包含 **436 个自动化测试用例**,分布在 12 个测试文件中,覆盖核心业务逻辑、数据库、安全中间件、备份与迁移、v3.1 资金安全等全链路场景: | 测试文件 | 测试数 | 覆盖范围 | |----------|--------|---------| | `tests/order-checkout.test.ts` | 38 | 结账条件、支付验证、餐桌管理、订单状态、加菜/取消 | | `tests/api-integration.test.ts` | 13 | API 集成测试、公共餐桌多订单、完整订单流程 | | `tests/e2e-full.test.ts` | 44 | 全模块 E2E 测试(22个功能模块) | | `tests/db-prisma.test.ts` | 16 | Prisma 数据库层、`getDatabaseUrl`、upsert 幂等初始化、KV 存储 | | `tests/postgresql.test.ts` | 42 | PostgreSQL 专属测试、索引/约束、级联清理、JSONB 字段、连接管理 | | `tests/middleware.test.ts` | 57 | 配置校验、CORS、限流、Helmet、错误处理、请求日志、CSRF、JWT 认证、bcrypt | | `tests/auth-csrf.test.ts` | 26 | JWT 签发与校验、密码 bcrypt 哈希、CSRF 双提交 Cookie 防护、角色权限 | | `tests/backup.test.ts` | 18 | JSON 备份、定时调度、保留期清理、备份恢复 | | `tests/migration.test.ts` | 35 | SQLite → PostgreSQL 数据迁移、记录数校证、kv_store 迁移、`--force` 选项 | | `tests/monitoring.test.ts` | 60 | 健康检查端点、Sentry 可选接入、Winston 日志、`captureException`、优雅关闭 | | `tests/v3.1-member-utils.test.ts` | 31 | v3.1 会员资金安全单元测试:DB 级乐观锁、积分流水、消费/退款流程、等级升级、积分过期逻辑、version 递增 | | `tests/v3.1-improvements.test.ts` | 56 | v3.1 改进功能集成测试:支付幂等、退款流水、优惠券校验、交班持久化、Refresh Token、SSE、KDS | ### 关键测试场景 - ✅ 公共餐桌占用后仍可创建新订单 - ✅ 大堂餐桌占用后拒绝新订单 - ✅ 包间占用后拒绝新订单 - ✅ 顾客端现金支付被拒绝 - ✅ 沙箱支付网关环境校验 - ✅ 未出餐时结账失败 - ✅ 全部出餐且全额支付后结账成功 - ✅ 已结账订单无法再次结账 - ✅ 加菜后 payPrice 增加、paidAmount 不变 - ✅ 取消未制作菜品 - ✅ 菜品状态流转 pending → preparing → ready - ✅ 管理端现金支付成功 - ✅ 早餐/午餐/晚餐时段菜品筛选 - ✅ PostgreSQL 索引、唯一约束、外键级联 - ✅ JWT 签发/校验/过期、bcrypt 密码哈希与明文迁移 - ✅ CSRF 双提交 Cookie 防护(GET 豁免、状态变更拦截) - ✅ JSON 备份生成、定时调度、过期清理与恢复 - ✅ SQLite → PostgreSQL 全量数据迁移与记录数校证 - ✅ 健康检查端点(数据库状态、内存、运行时长、Sentry 状态) - ✅ v3.1 支付幂等性(idempotencyKey 缓存结果、重复请求不产生多笔支付) - ✅ v3.1 退款流水记录(RefundRecord、网关回调、对账状态) - ✅ v3.1 会员乐观锁(DB 级原子 `WHERE version = ?` 校验、version 字段递增、本金优先扣减、409 冲突响应) - ✅ v3.1 积分流水审计(PointTransaction 充值/消费/退款/过期全链路) - ✅ v3.1 优惠券强校验(过期/停用/门槛/赠菜/perMemberLimit 限领) - ✅ v3.1 交班持久化(CashTransaction 现金流水、双人确认 confirmedBy) - ✅ v3.1 Refresh Token(7 天有效期、type=refresh 声明、刷新换新) - ✅ v3.1 动态权限(RolePermission 表、管理员可编辑角色权限) - ✅ v3.1 排队 SSE 实时推送 + 动态等待时间估算 - ✅ v3.1 KDS 增强(状态流转 pending→preparing→ready→served、超时预警、kdsItems 汇总) 运行测试: ```bash # 运行全部测试(测试环境使用 eateasy_test 数据库,自动 TRUNCATE 清理) npx vitest run # 运行截图测试 npx playwright test tests/screenshots.spec.cjs ``` ## 技术栈 | 层 | 技术 | |---|---| | 前端 | React 18 + TypeScript + Tailwind CSS 3 + Vite | | 状态管理 | Zustand | | 路由 | React Router DOM v6 | | 图标 | lucide-react | | 图表 | Recharts | | 后端 | Express 4 + TypeScript (ESM) | | 数据库 | PostgreSQL 17 + Prisma ORM 5.22(`prisma/schema.prisma`) | | 认证 | JWT(`jsonwebtoken`)+ bcrypt 密码哈希(`bcryptjs`) | | 安全 | CSRF 双提交 Cookie、Helmet 安全头、CORS 白名单 | | 限流 | `express-rate-limit`(全局限流 + 登录限流) | | 日志 | Winston(生产环境文件转储) | | 监控 | 可选 Sentry(`SENTRY_DSN`)+ 增强健康检查 `/api/health` | | 备份 | JSON 自动备份 + 定时调度(`BACKUP_INTERVAL_HOURS`) | | 配置 | `.env` 环境变量(`dotenv`),生产环境强制校验关键变量 | | 测试 | Vitest 4(`fileParallelism: false` + 测试环境 `eateasy_test` 数据库) | ## 快速开始 ### 环境要求 - Node.js >= 18 - PostgreSQL >= 14(推荐 17) ### 安装与运行 ```bash # 1. 安装依赖 npm install # 2. 创建数据库(开发环境用 eateasy,测试环境用 eateasy_test) createdb eateasy createdb eateasy_test # 3. 复制环境变量模板并修改数据库连接等信息 cp .env.example .env # 4. 执行 Prisma 数据库迁移(创建表结构与初始数据) npx prisma migrate dev --name init # 5. 启动开发服务器(前后端同时启动) npm run dev ``` - 前端:http://localhost:5173 - 后端 API:http://localhost:3001 - 管理端:http://localhost:5173/admin > 详细部署流程(PM2、Nginx 反向代理、SSL、自动备份、监控、Docker 等)请参阅 [部署手册](docs/deployment-guide.md)。 ### 默认测试账号 | 角色 | 用户名 | 密码 | 说明 | |------|--------|------|------| | 超级管理员 | admin | admin123 | 全部权限 | | 店长 | manager | manager123 | 除员工管理、支付设置外的权限 | | 收银员 | cashier | cashier123 | 收银、退款、发票、交班等 | | 服务员 | waiter | waiter123 | 点餐、餐桌、排队、预定 | | 后厨 | kitchen | kitchen123 | 查看订单 | ### 构建部署 ```bash # 类型检查 npm run check # 构建前端 npm run build # 从旧 SQLite 数据库迁移数据到 PostgreSQL(可选) npm run migrate # 生产环境启动(含配置校验、监控、备份调度、优雅关闭) npm run start ``` 生产环境部署完整流程(PM2、Nginx 反向代理、SSL、备份、监控、Docker 等)请参阅 [部署手册](docs/deployment-guide.md)。 ## 项目结构 ``` EatEasy/ ├── api/ # 后端代码 │ ├── routes/ # API 路由(20个模块) │ │ ├── auth.ts # 认证与权限(登录、CSRF token) │ │ ├── categories.ts # 菜品分类 │ │ ├── dishes.ts # 菜品管理 │ │ ├── orders.ts # 订单管理(含结账、加菜、取消菜品) │ │ ├── payments.ts # 支付处理(含支付来源校验) │ │ ├── refunds.ts # 退款管理 │ │ ├── members.ts # 会员管理 │ │ ├── tables.ts # 餐桌管理 │ │ ├── reservations.ts # 预定管理 │ │ ├── stats.ts # 统计报表 │ │ ├── delivery.ts # 外卖对接 │ │ ├── invoices.ts # 发票管理 │ │ ├── coupons.ts # 优惠券 │ │ ├── queue.ts # 排队管理 │ │ ├── shift.ts # 交班管理 │ │ ├── payment-gateways.ts # 支付网关管理 │ │ ├── staff.ts # 员工管理 │ │ └── system-settings.ts # 系统设置(含测试模式) │ ├── middleware/ # 中间件层 │ │ ├── auth.ts # JWT 认证、角色权限 │ │ ├── csrf.ts # CSRF 双提交 Cookie 防护 │ │ ├── errorHandler.ts # 统一错误处理、404、asyncHandler │ │ ├── rateLimiter.ts # 全局限流 + 登录限流 │ │ └── requestLogger.ts # 请求日志 │ ├── lib/ # 业务支撑库 │ │ ├── monitoring.ts # 监控(Sentry 可选 + 健康检查) │ │ ├── backup.ts # JSON 自动备份与定时调度 │ │ └── password.ts # bcrypt 密码哈希(含明文迁移) │ ├── scripts/ # 运维脚本 │ │ └── migrate-to-prisma.ts # SQLite → PostgreSQL 数据迁移 │ ├── app.ts # Express 应用配置(中间件栈) │ ├── server.ts # 生产入口(配置校验、监控、备份、优雅关闭) │ ├── db-prisma.ts # Prisma 数据库层(getDb、closeDb、upsert 初始化) │ ├── db.ts # 数据库访问统一入口(重导出 db-prisma) │ ├── config.ts # 环境配置 + validateProductionConfig │ ├── logger.ts # Winston 日志 │ └── types.ts # 后端类型定义 ├── prisma/ # Prisma ORM │ └── schema.prisma # PostgreSQL 数据模型(26 张业务表 + kv_store) ├── src/ # 前端代码 │ ├── components/ # 共享组件 │ │ ├── admin/ui/ # 管理端UI组件库 │ │ └── member/ # 会员相关组件 │ ├── pages/ │ │ ├── customer/ # 顾客端页面 │ │ └── admin/ # 管理端页面 │ ├── store/ # Zustand 状态管理 │ ├── lib/ # 工具函数、API 封装 │ ├── types/ # 前端类型定义 │ └── App.tsx # 路由配置 ├── tests/ # 测试(10 个测试文件,349 个用例) │ ├── global-setup.ts # 测试库 TRUNCATE CASCADE 清理 │ └── *.test.ts # 业务/数据库/中间件/备份/迁移/监控测试 ├── docs/ # 文档和截图 │ ├── deployment-guide.md # 部署手册 │ └── database-migration-guide.md # 数据库迁移指南 ├── .env.example # 环境变量模板 ├── .trae/documents/ # 产品需求文档和技术架构文档 └── package.json ``` ## API 概览 | 模块 | 端点示例 | |------|---------| | 认证 | `POST /api/auth/login`, `POST /api/auth/verify-password` | | 分类 | `GET /api/categories` | | 菜品 | `GET /api/dishes?categoryId=&keyword=` | | 订单 | `POST /api/orders`, `GET /api/orders`, `PATCH /api/orders/:id/status`, `POST /api/orders/:id/checkout`, `POST /api/orders/:id/add-items`, `POST /api/orders/:id/cancel-items` | | 会员 | `POST /api/members`, `POST /api/members/:id/recharge` | | 支付 | `POST /api/payments` | | 支付网关 | `GET /api/payment-gateways`, `PUT /api/payment-gateways/:id` | | 退款 | `POST /api/refunds` | | 餐桌 | `GET /api/tables`, `PATCH /api/tables/:id` | | 预定 | `POST /api/reservations`, `PUT /api/reservations/:id/cancel` | | 排队 | `POST /api/queue`, `POST /api/queue/:id/call` | | 统计 | `GET /api/stats/overview`, `GET /api/stats/revenue`, `GET /api/stats/dimension-revenue` | | 外卖 | `GET /api/delivery/status`, `POST /api/delivery/webhook/:platform` | | 发票 | `POST /api/invoices`, `POST /api/invoices/:id/replace`, `GET /api/invoices/quota-usage` | | 优惠券 | `GET /api/coupons`, `POST /api/coupons` | | 交班 | `POST /api/shift/change`, `GET /api/shift/history` | | 系统设置 | `GET /api/system-settings`, `PUT /api/system-settings` | ## 设计特色 - **暖橙色系**:主色调 #F97316,营造温暖食欲感 - **移动优先**:顾客端针对手机扫码场景优化 - **桌面管理**:侧边栏 + 内容区布局,适合收银台使用 - **打印支持**:58mm/80mm 热敏纸小票、A4 发票样式 - **智能预定**:根据时间临近程度智能判断餐桌可用性 - **多维度统计**:支持按堂食/带走/时段/外卖平台等维度分析 - **定金管理**:可设定预定定金比例,取消自动退回 - **支付安全**:顾客端/管理端支付权限分离,沙箱网关环境隔离 - **餐桌智能管理**:公共餐桌多订单、包间独占、结账自动释放 - **时段定价**:早餐/午餐/晚餐差异化定价,代客点餐支持时段筛选 ## 文档 - [产品需求文档](.trae/documents/prd.md) - [技术架构文档](.trae/documents/technical-architecture.md) - [部署手册](docs/deployment-guide.md) - [数据库迁移指南](docs/database-migration-guide.md)