# 扫码桌号点餐需求文档

**Feature Branch**: `004-qr-table-order`
**Created**: 2026-04-30
**Status**: Draft
**Input**: 用户扫码点餐，下单时订单关联餐桌码，商家根据桌号送餐

## 背景

餐桌码（table_qrcode）功能已实现（spec 002），包含码的创建、管理、扫码入口。本需求完成扫码到下单的最后一环：扫桌码后订单自动关联餐桌码，商家可看到桌号并送餐到对应餐桌。

## 用户场景与测试

### 用户故事 1 - 扫档口码点餐下单 (Priority: P1)

用户在摊位餐桌上扫描档口码，APP 进入该摊位菜单页，用户选商品下单，订单自动关联到该餐桌码，商家看到桌号后送餐。

**Why this priority**: 这是最核心的扫码点餐流程，覆盖最常见场景。

**Independent Test**: 创建一个档口码，扫码进入菜单，下单后检查订单是否包含正确的 tableId 和 tableNum。

**Acceptance Scenarios**:

1. **Given** 一个已启用的档口码（type=0）存在, **When** 用户扫码进入菜单并下单, **Then** 订单的 tableId 关联到该码，tableNum 为码记录中的桌号，订单 type=2（堂食）
2. **Given** 一个已停用的档口码, **When** 用户扫码后尝试下单, **Then** 系统拒绝并提示餐桌码已停用

---

### 用户故事 2 - 扫通用码点餐下单 (Priority: P2)

用户在夜市公共餐桌上扫描通用码，APP 显示该夜市所有摊位，用户选择摊位后进入菜单，下单时订单关联到该公共餐桌码。

**Why this priority**: 夜市公共餐桌场景，用户需要额外选择摊位步骤，是第二常见的流程。

**Independent Test**: 创建一个通用码（type=1），扫码进入摊位列表，选择摊位下单，检查订单包含正确的 tableId。

**Acceptance Scenarios**:

1. **Given** 一个已启用的通用码（type=1）存在, **When** 用户扫码、选择摊位、下单, **Then** 订单的 tableId 关联到该通用码，tableNum 为码记录中的桌号
2. **Given** 通用码关联的夜市下有多个摊位, **When** 用户选择不同摊位分别下单, **Then** 每个订单的 tableId 都指向同一个通用码

---

### 用户故事 3 - 商家查看堂食订单桌号 (Priority: P3)

商家在订单列表中看到堂食订单的桌号信息，据此送餐到对应餐桌。

**Why this priority**: 这是商家侧的必要展示，但实现简单（数据已有，只需前端展示）。

**Independent Test**: 创建一个带桌号的堂食订单，商家端查看该订单，确认桌号正确显示。

**Acceptance Scenarios**:

1. **Given** 存在一个带桌号的堂食订单, **When** 商家查看订单详情, **Then** 订单中显示桌号（如"A01"）
2. **Given** 存在一个非堂食订单（外送/自取）, **When** 商家查看订单详情, **Then** 订单中桌号字段为空，不显示桌号

---

### Edge Cases

- 用户扫了一个已被删除的餐桌码的二维码：下单时应报错"餐桌码不存在"
- 用户扫码后中途退出 APP 再回来：前端丢失 tableId 参数，按普通下单处理（tableId 为空）
- 同一桌多人各自扫码下单：每次独立下单，各自订单都带同一个 tableId，不做合并或冲突检测

## 需求

### 功能需求

- **FR-001**: 下单接口 MUST 接受可选的 tableId 参数，关联到 table_qrcode 记录
- **FR-002**: 当 tableId 不为空时，系统 MUST 校验该码存在且未停用，不存在或已停用则拒绝下单
- **FR-003**: 当 tableId 不为空时，系统 MUST 以码记录中的 tableNo 作为订单的 tableNum，忽略前端传入值，确保数据一致性
- **FR-004**: 当 tableId 为空时，按现有流程正常下单，不做额外校验
- **FR-005**: 商家端订单详情 MUST 展示堂食订单的桌号信息

### 关键实体

- **PosOrder（订单）**: 新增 tableId 字段，关联餐桌码记录。已有 tableNum 字段存储桌号。
- **OrderParent（父订单）**: 同样新增 tableId 字段，与子订单保持一致。
- **TableQrcode（餐桌码）**: 已有实体，本需求不改动其结构。

## 成功标准

### 可衡量结果

- **SC-001**: 扫桌码下单后，订单的 tableId 和 tableNum 正确关联到对应餐桌码记录
- **SC-002**: 非扫码下单（tableId 为空）不受影响，现有流程正常运作
- **SC-003**: 传入无效或已停用的 tableId 时，系统在 1 秒内返回明确的错误提示
- **SC-004**: 商家端能正确显示堂食订单的桌号

## 假设

- 用户必须已下载 APP 并登录才能扫码点餐（不做 H5/游客模式）
- 前端负责在扫码后的整个点餐流程中携带 tableId，直到下单时传入
- 不做餐桌状态管理（不追踪占用/空闲）
- 不做多次加餐/拼单功能
- 不做按桌号分组查询，只在订单上显示桌号
- 现有下单接口（/system/userOrder/createOrder）已处理 tableNum，本需求新增 tableId

## 不在范围内

- 餐桌占用状态管理
- 多次加餐、拼单、合并订单
- 按桌号分组的订单视图
- 扫码频率限制
- C 端扫码页面开发（仅后端接口改动）
