# 扫码桌号点餐设计

日期: 2026-04-30

## 背景

用户在 APP 中扫描餐桌二维码进入菜单点餐，订单需要关联到具体的餐桌码，商家根据订单上的桌号送餐。

## 现有基础

- `TableQrcode` 实体和完整 CRUD API 已实现（创建、列表、扫码入口等）
- `PosOrder` 已有 `tableNum` 字段和 `type=2`（堂食）订单类型
- `OrderCreateInput` 已接收 `tableNum`
- `UserOrderController` 已将 `tableNum` 写入父订单和子订单
- 扫码入口 `/table-qrcode/scan` 已根据码类型跳转，URL 携带 `tableId`

两种餐桌码：
- **档口码**（type=0）：直接进入该档口菜单
- **通用码**（type=1）：进入夜市所有档口选择页

## 方案

前端全程携带 tableId/tableNum，下单时作为可选参数传入。不做后端会话绑定，不做 Redis 存储。

## 数据流

```
用户扫桌码
  → app 调用 /table-qrcode/scan?tableId=xxx（已有）
  → app 从 URL 获取 tableId
  → 用户浏览菜单、选商品
  → 提交订单时传入 tableId（可选）+ tableNum（可选）
  → 后端校验 tableId 有效性，以码记录中的 tableNo 为桌号权威来源
  → 写入 PosOrder.tableId + PosOrder.tableNum
  → 商家端订单详情展示桌号
```

## 后端改动

### 1. 数据库

```sql
ALTER TABLE pos_order ADD COLUMN table_id BIGINT DEFAULT NULL COMMENT '餐桌码ID';
```

如果 `order_parent` 表也需要记录 tableId，同理加字段。

### 2. PosOrder 实体

新增字段：

```java
/** 餐桌码ID（关联 table_qrcode 表） */
private Long tableId;
```

`tableNum` 已存在，保持不变。

### 3. OrderCreateInput DTO

新增字段：

```java
/** 餐桌码ID（可选，扫码点餐时传入） */
private Long tableId;
```

### 4. OrderParent（如需要）

同样新增 `tableId` 字段，与 `tableNum` 对应。

### 5. UserOrderController

在 `createOrderChild` 方法中，`posOrder.setTableNum(input.getTableNum())` 旁新增：

```java
posOrder.setTableId(input.getTableId());
```

`createOrderParent` 同理。

### 6. 校验逻辑

如果 `tableId != null`：
1. 查询 `table_qrcode` 表，确认码存在且未停用（status != 1）
2. 从码记录中取出 `tableNo`，覆盖前端传入的 `tableNum`（以数据库为准）
3. 码不存在或已停用则报错

```java
if (input.getTableId() != null) {
    TableQrcode qrcode = tableQrcodeService.selectTableQrcodeById(input.getTableId());
    if (qrcode == null) {
        throw new ServiceException("餐桌码不存在");
    }
    if (qrcode.getStatus() != null && qrcode.getStatus() == 1) {
        throw new ServiceException("该餐桌码已停用");
    }
    input.setTableNum(qrcode.getTableNo());
}
```

### 7. 商家端展示

无需新页面。`PosOrder` 返回时自动包含 `tableId` 和 `tableNum`，商家端前端在订单详情中展示桌号即可。

## 不涉及的范围

- 餐桌状态管理（占用/释放）
- 多次加餐/拼单
- 按桌号分组查询
- 扫码频率限制

## 影响文件清单

| 文件 | 改动 |
|------|------|
| `PosOrder.java` | 新增 `tableId` 字段 |
| `OrderCreateInput.java` | 新增 `tableId` 字段 |
| `OrderParent.java` | 新增 `tableId` 字段（如需要） |
| `UserOrderController.java` | 设置 `tableId`，新增校验逻辑 |
| SQL 迁移 | `pos_order` 加 `table_id` 列 |
