# API Contracts: Table QR Code

Base URL: `/table-qrcode`

Authentication: 所有接口需要 `@Anonymous` + `@Auth`，通过 `@RequestHeader String token` 进行 JWT 认证。

---

## 1. 创建餐桌码

**POST** `/table-qrcode/add`

### Request

```json
{
  "tableNo": "A01",
  "type": 0,
  "storeId": 100,
  "remark": "靠窗位置"
}
```

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| tableNo | string | YES | 桌号，1-32 字符 |
| type | int | YES | 0=摊位码, 1=公用码 |
| storeId | long | CONDITIONAL | 摊位码时必填，公用码时忽略 |
| remark | string | NO | 备注 |

### Response

```json
{
  "code": 200,
  "msg": "操作成功",
  "data": {
    "id": 1,
    "tableNo": "A01",
    "type": 0,
    "storeId": 100,
    "nightMarketId": 5,
    "qrCode": "https://xxx.com/scan?type=0&storeId=100&tableId=1",
    "status": 0,
    "useStatus": 0,
    "createTime": "2026-04-29 10:00:00"
  }
}
```

### Business Rules

- 摊主只能创建 type=0，storeId 自动从用户信息获取
- 夜市管理员可创建 type=0（需指定 storeId）和 type=1
- 同一摊位/夜市下桌号不能重复

---

## 2. 获取餐桌码列表

**GET** `/table-qrcode/list`

### Request Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| storeId | long | NO | 按摊位筛选 |
| type | int | NO | 按类型筛选 |
| status | int | NO | 按启用状态筛选 |
| useStatus | int | NO | 按使用状态筛选 |
| pageNum | int | NO | 页码，默认 1 |
| pageSize | int | NO | 每页条数，默认 10 |

### Response

```json
{
  "code": 200,
  "msg": "操作成功",
  "data": [
    {
      "id": 1,
      "tableNo": "A01",
      "type": 0,
      "storeId": 100,
      "storeName": "烧烤摊",
      "nightMarketId": 5,
      "status": 0,
      "useStatus": 0,
      "createTime": "2026-04-29 10:00:00"
    }
  ]
}
```

### Business Rules

- 摊主只能看到自己摊位的餐桌码
- 夜市管理员可以看到夜市下所有餐桌码

---

## 3. 获取餐桌码详情

**GET** `/table-qrcode/{id}`

### Response

同创建响应中的 data 结构，额外包含 storeName。

---

## 4. 更新餐桌码

**PUT** `/table-qrcode/update`

### Request

```json
{
  "id": 1,
  "tableNo": "A02",
  "remark": "更新备注"
}
```

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| id | long | YES | 餐桌码 ID |
| tableNo | string | NO | 桌号 |
| remark | string | NO | 备注 |

### Response

```json
{
  "code": 200,
  "msg": "操作成功"
}
```

### Business Rules

- 不允许修改 type 和 storeId（创建后不可变更）
- 摊主只能修改自己的码，夜市管理员可修改所有码

---

## 5. 删除餐桌码

**DELETE** `/table-qrcode/delete/{id}`

### Response

```json
{
  "code": 200,
  "msg": "操作成功"
}
```

### Business Rules

- 使用中的餐桌码（useStatus=1）不能删除
- 摊主只能删除自己的码，夜市管理员可删除所有码

---

## 6. 切换启用状态

**PUT** `/table-qrcode/changeStatus`

### Request

```json
{
  "id": 1,
  "status": 1
}
```

### Response

```json
{
  "code": 200,
  "msg": "操作成功"
}
```

---

## 7. 获取二维码图片

**GET** `/table-qrcode/qrcode/{id}`

### Response

返回二维码图片的 Base64 编码：

```json
{
  "code": 200,
  "msg": "操作成功",
  "data": "data:image/png;base64,iVBORw0KGgo..."
}
```

### Business Rules

- 根据餐桌码信息动态生成二维码图片
- 二维码内容为 qrCode 字段中的 URL
- 如果 qrCode 为空，先根据 id 生成 URL 并保存到 qrCode 字段

---

## 8. 扫码入口（C端）

**GET** `/table-qrcode/scan`

### Request Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| type | int | YES | 0=摊位码, 1=公用码 |
| storeId | long | CONDITIONAL | type=0 时必填 |
| tableId | long | YES | 餐桌码 ID |

### Response

返回重定向到对应的前端页面：

- type=0: 重定向到摊位商品列表页（携带 storeId + tableId）
- type=1: 重定向到摊位选择页（携带 nightMarketId + tableId）

### Business Rules

- 餐桌码必须处于启用状态（status=0）
- 同时更新 useStatus 为 1（使用中）
